﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.ServiceModel.DomainServices.Client;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media.Imaging;
using System.Windows.Printing;
using System.Windows.Resources;
using NetBay.Core.Silverlight.Extensions;
using NetBay.Core.Silverlight.Log;
using Rio.Applications.Web.Services;
using Rio.Framework.Localisation;
using Rio.Framework.Pages.AppCode.Helpers;
using Rio.Framework.Pages.Helpers;
using Rio.Framework.Pages.Helpers.Utils;
using Rio.Framework.Pages.Manager;
using Rio.Framework.WCFService;
using Rio.Framework.WCFService.RioWcfServices;
using Telerik.Windows.Controls;
using Telerik.Windows.Media.Imaging;
using Document = NetBay.Core.BusinessEntities.Document;
using Folder = NetBay.Core.BusinessEntities.Folder;
using VersioningItem = NetBay.Core.BusinessEntities.Versioning.VersioningItem;
using Rio.Framework.Pages.AppCode.Enums;
using System.Net;
using GalaSoft.MvvmLight.Command;
using Rio.Framework.Pages.ChildWindows;
using Rio.Framework.Pages.Extensions;
using Rio.Framework.Pages.Context;


namespace Rio.Framework.Pages.Viewer
{
    public partial class UCViewer : UCViewerCore
    {
        #region Attributes

        public RelayCommand<string> ToolBarNavigationClickCommand { get; set; }
        public RelayCommand<KeyEventArgs> PerformChangeDocumentCommand { get; set; }
        public RelayCommand<KeyEventArgs> PerformChangePageCommand { get; set; }

        private bool isOldVersionDisplayed;
        int m_iCallServiceNbAttempt = 0;
        private BitmapImage m_biImageViewer;
        private int m_iNbOfPage = 1;
        private int m_iIndexPage = 1;
        public byte[] m_aRawImage;
        private int m_iOldSelectedDocumentIndex;
        private List<string> m_oDocumentFulltextNameList;
        private string m_sConvertingPDF = string.Empty;
        private double[] m_iImageViewWidth = new Double[] { 800, 800 };
        private double[] m_iImageViewHeight = new Double[] { 600, 600 };
        public Document m_oCurrentDocument;
        private List<string> m_oFilenamesToConvert = new List<string>();
        private int m_iCurrentIndextoFilenamesToConvert = 0;
        private Guid m_oGuidSessionToConvert;
        private List<int> m_oSearchPages;
        private string m_sCurrentSearchWord;
        private int m_iLastSearchPage;
        private string m_sMsgEndOfTheDocument;
        private bool _defaultFitToHeight = false;
        private double _defaultZoomStep = 1;

        #endregion

        #region Properties

        public override bool ScanImportIsEnabled
        {
            get
            {
                return base.ScanImportIsEnabled;
            }
            set
            {
                base.ScanImportIsEnabled = value;
                if (DocumentToolbar != null)
                {
                    DocumentToolbar.ScanImportIsEnabled = value;
                    DocumentToolbar.ManageToolbar();
                }
            }
        }

        /// <summary>
        /// Return the file name selected
        /// </summary>
        protected override string GetFileNameSelected
        {
            get
            {
                string l_szRet = string.Empty;

                if (!isOldVersionDisplayed)
                {

                    try
                    {

                        if (ListAllDocFileName != null
                            && ListAllDocFileName.Count > 0
                            && SelectedDocumentIndex != -1
                            && SelectedDocumentIndex < ListAllDocFileName.Count)
                        {
                            l_szRet = ListAllDocFileName[SelectedDocumentIndex];
                        }
                    }
                    catch (ArgumentOutOfRangeException)
                    {
                        //reset index to prevent outofrangeexcpeton
                        SelectedDocumentIndex = 0;
                        if (ListAllDocFileName != null
                            && ListAllDocFileName.Count > 0)
                        {
                            l_szRet = ListAllDocFileName[SelectedDocumentIndex];
                        }
                    }

                }
                else
                {
                    l_szRet = versionRelativeFilepath;
                }

                return l_szRet;
            }
        }

        /// <summary>
        /// Gets the get document se selected.
        /// </summary>
        /// <value>The get document se selected.</value>
        protected Document CurrentDocument
        {
            get
            {
                try
                {

                    if (ListDocument != null
                        && ListDocument.Count > 0
                        && SelectedDocumentIndex != -1
                        && SelectedDocumentIndex < ListDocument.Count)
                    {
                        return ListDocument[SelectedDocumentIndex];
                    }
                }
                catch (ArgumentOutOfRangeException)
                {
                    //reset index to prevent outofrangeexcpeton
                    SelectedDocumentIndex = 0;
                    if (ListDocument != null
                        && ListDocument.Count > 0)
                    {
                        return ListDocument[SelectedDocumentIndex];
                    }
                }

                return null;
            }
        }

        /// <summary>
        /// Get or set the current selected image
        /// </summary>
        public override ImageRio CurrentSelectedImage
        {
            get
            {
                ImageRio l_szRet = null;
                if (m_oItemsSource != null
                    && m_oItemsSource.Count > 0
                    && SelectedDocumentIndex != -1
                    && SelectedDocumentIndex < m_oItemsSource.Count)
                {
                    l_szRet = m_oItemsSource[SelectedDocumentIndex];
                }

                return l_szRet;
            }
            set
            {
                base.CurrentSelectedImage = value;
            }
        }

        /// <summary>
        /// Return the index of desired document
        /// </summary>
        protected int OldSelectedDocumentIndex
        {
            get { return m_iOldSelectedDocumentIndex; }
            set
            {
                int l_iOldSelectedValue = value;
                if (l_iOldSelectedValue < 0)
                    l_iOldSelectedValue = -1;
                if (l_iOldSelectedValue >= ListAllDocFileName.Count)
                    l_iOldSelectedValue = ListAllDocFileName.Count - 1;
                m_iOldSelectedDocumentIndex = l_iOldSelectedValue;
            }
        }

        /// <summary>
        /// Gets or sets the index page.
        /// </summary>
        /// <value>The index page.</value>
        public int IndexPage
        {
            get { return m_iIndexPage; }
            set { m_iIndexPage = value; }
        }

        /// <summary>
        /// Defines if the viewer is in Fit Height Mode (true) or in Fit Width Mode (false)
        /// </summary>
        public bool IsInFitHeightMode { get; set; }

        #endregion

        #region EventHandler

        public event EventHandler CreateNewVersionClick;
        protected virtual void OnCreateNewVersionClick()
        {
            if (CreateNewVersionClick != null)
                CreateNewVersionClick(this, EventArgs.Empty);
        }

        public event EventHandler MakeThisVersionToMajorClick;
        protected virtual void OnMakeThisVersionToMajorClick()
        {
            if (MakeThisVersionToMajorClick != null)
                MakeThisVersionToMajorClick(this, EventArgs.Empty);
        }

        public event EventHandler DocumentChanging;
        protected void OnDocumentChanging()
        {
            if (DocumentChanging != null)
                DocumentChanging(this, EventArgs.Empty);
        }

        #endregion

        #region Constructor

        /// <summary>
        /// Initializes a new instance of the <see cref="UCViewer" /> class.
        /// </summary>
        public UCViewer()
            : this(null, AppDisplayMode.None)
        { }

        /// <summary>
        /// Initializes a new instance of the <see cref="UCViewer" /> class.
        /// </summary>
        /// <param name="p_oListDocument">The list document.</param>
        /// <param name="p_oDisplayModeMode">The display mode mode.</param>
        /// <param name="p_oCurrentFolder">The current folder.</param>
        /// <param name="p_oOrganization">The organization.</param>
        /// <param name="p_oFolderType">Type of the p_o folder.</param>
        public UCViewer(List<Document> p_oListDocument, AppDisplayMode p_oDisplayModeMode, Folder p_oCurrentFolder = null, NetBay.Core.BusinessEntities.Organization p_oOrganization = null, NetBay.Core.BusinessEntities.FolderType p_oFolderType = null)
            : base(p_oListDocument, p_oDisplayModeMode)
        {
            try
            {

                InitializeComponent();

                //Get settings 
                LoadGeneralSettings();

                ChangeDisplayMode(p_oDisplayModeMode);

                // Initialize all labels for this class
                InitLabel();
                ActivateKeyPress();

                IndexPage = 1;

                //Create the Print Document
                PrintDocument = new PrintDocument();

                //Init document toolbar
                DocumentToolbar.DocumentRibbonBarEvent += DocumentToolbar_DocumentRibbonBarEvent;
                DocumentToolbar.ViewMode = AppViewMode.Single;
                DocumentToolbar.ManageToolbar();

                //Init document context menu
                RadContextMenu.SetContextMenu(ImageViewer, DocumentContextMenu.ContextMenu);
                DocumentContextMenu.ViewMode = AppViewMode.Single;
                DocumentContextMenu.ManageContextMenuItemState();
                DocumentContextMenu.DocumentContextMenuEvent += DocumentToolbar_DocumentRibbonBarEvent;

                m_oFolder = p_oCurrentFolder;
                m_oCurrentFolderType = p_oFolderType;
                m_oCurrentOrganization = p_oOrganization;

                if (CurrentDisplayMode == AppDisplayMode.Search && p_oCurrentFolder != null && p_oCurrentFolder.FullTextDocList != null)
                {
                    m_oDocumentFulltextNameList = new List<string>(p_oCurrentFolder.FullTextDocList);
                    DocumentToolbar.SetAvailability(DocumentRibbonBarMenuItems.SearchNext, true);
                    DocumentToolbar.SetAvailability(DocumentRibbonBarMenuItems.SearchPrevious, true);
                }
                else
                {
                    DocumentToolbar.SetAvailability(DocumentRibbonBarMenuItems.SearchNext, false);
                    DocumentToolbar.SetAvailability(DocumentRibbonBarMenuItems.SearchPrevious, false);
                }

                //Init Print Area control
                PrintArea.ParentContainer = this;

                //Initialize MvvmCommand
                InitCommand();
            }
            catch (Exception ex)
            {
                MessageBoxChildWindow msg = new MessageBoxChildWindow("ERREUR 1090", ex.Message, MessageBoxButtons.Ok, MessageBoxIcon.Information);
                msg.MessageDetail = ex.Message;
                msg.Show();
            }
        }

        #endregion

        #region Initialization

        /// <summary>
        /// Translation
        /// </summary>
        public override void InitLabel()
        {
            PageMenuLabel.Content = Resx.GetLabel(ResxCommon.PAGE_LABEL);
            LabelSaveModificationImage = Resx.GetLabel(ResxCommon.SAVE_IMAGE_MODIFICATION_CONFIRMATION);
            LabelDeleteThumbnail = Resx.GetLabel(ResxCommon.DELETE_THUMBNAIL_CONFIRMATION);
            TextBlockMode.Text = Resx.GetLabel(ResxCommon.MODE_VIEWER);
            m_sMsgEndOfTheDocument = Resx.GetLabel(ResxCommon.MSG_END_OF_DOCUMENT);
            DocumentPrintArea.Header = Resx.GetLabel(ResxCommon.DOCUMENT_PRINT);
            LabelMergePdfQuestion = Resx.GetLabel(ResxCommon.MERGE_PDF_QUESTION);
            LabelRotateUnsupportedFile = Resx.GetLabel(ResxListVignetteSearch.ROTATE_UNSUPPORTED_FILE);
            DocumentMenuLabel.Content = Resx.GetLabel(ResxCommon.DOCUMENT_LABEL);

            NextDocument.SetValue(ToolTipService.ToolTipProperty, Resx.GetLabel(ResxCommon.NEXTDOC));
            PreviousDocument.SetValue(ToolTipService.ToolTipProperty, Resx.GetLabel(ResxCommon.PREVIOUSDOC));
        }

        /// <summary>
        /// Inits the command.
        /// </summary>
        private void InitCommand()
        {
            ToolBarNavigationClickCommand = new RelayCommand<string>(NavigationToolbarActionPerformed);

            PerformChangeDocumentCommand = new RelayCommand<KeyEventArgs>(ChangeDocumentActionPerformed);

            PerformChangePageCommand = new RelayCommand<KeyEventArgs>(ChangePageActionPerformed);
        }

        #endregion

        #region Load and convert document

        /// <summary>
        /// Load an image from a document
        /// </summary>
        /// <param name="P_sUserId">UserID</param>
        /// <param name="P_oListImportFileName">List of all file name document</param>
        /// <param name="P_iLoadedDocument">Index's document to extract an image</param>
        /// <param name="P_bOnSearch">Indicate if we are in mode search or not</param>
        /// <param name="p_oVersionNumber">The p_o version number.</param>
        public void LoadImageFromDocument(long P_sUserId, List<string> P_oListImportFileName, int P_iLoadedDocument, bool P_bOnSearch, string p_oVersionNumber = "")
        {
            UserId = P_sUserId;

            ListAllDocFileName = P_oListImportFileName;

            SelectedDocumentIndex = P_iLoadedDocument;

            if (ListAllDocFileName == null || ListAllDocFileName.Count == 0)
            {
                TextBlockMode.Visibility = System.Windows.Visibility.Visible;
                ReinitializeViewer();
            }
            else
            {
                TextBlockMode.Visibility = System.Windows.Visibility.Collapsed;

                // Retrieve the document
                GetSourceDocument(IndexPage, IndexPage, true, p_oVersionNumber);
            }

            EnableDisableMenu();
        }

        /// <summary>
        /// Load an image from a document
        /// </summary>
        /// <param name="P_sUserId">UserID</param>
        /// <param name="P_iLoadedDocument">Index's document to extract an image</param>
        /// <param name="P_bOnSearch">Indicate if we are in mode search or not</param>
        /// <param name="FileName">Name of the file.</param>
        /// <param name="p_oVersionNumber">The p_o version number.</param>
        public void LoadImageFromDocument(long P_sUserId, int P_iLoadedDocument, bool P_bOnSearch, string FileName, string p_oVersionNumber = "")
        {
            UserId = P_sUserId;

            SelectedDocumentIndex = P_iLoadedDocument;
            TextBlockMode.Visibility = System.Windows.Visibility.Collapsed;

            // Retrieve the document
            versionRelativeFilepath = FileName;
            GetSourceDocument(IndexPage, IndexPage, true, p_oVersionNumber);

            EnableDisableMenu();
        }

        /// <summary>
        /// Gets the source document.
        /// </summary>
        /// <param name="p_iStartPage">The p_i start page.</param>
        /// <param name="p_iEndPage">The p_i end page.</param>
        /// <param name="p_bDisplaySplashScreen">if set to <c>true</c> [P_B display splash screen].</param>
        /// <param name="p_oVersionNumber">The p_o version number.</param>
        private void GetSourceDocument(int p_iStartPage, int p_iEndPage, bool p_bDisplaySplashScreen = false, string p_oVersionNumber = "")
        {
            try
            {
                ImageViewer.Viewer.ScaleFactor = 1;

                var l_oFileFormat = new List<object>(EnumHelper.GetValues(typeof(Constant.DocumentFileFormat))).Where<object>(c => ((Constant.DocumentFileFormat)c).szGetDescription().Equals(Path.GetExtension(GetFileNameSelected), StringComparison.CurrentCultureIgnoreCase)).FirstOrDefault();

                if (l_oFileFormat != null && !l_oFileFormat.Equals(Constant.DocumentFileFormat.TXT)
                    && !l_oFileFormat.Equals(Constant.DocumentFileFormat.XLS)
                    && !l_oFileFormat.Equals(Constant.DocumentFileFormat.XLSX)
                    && !l_oFileFormat.Equals(Constant.DocumentFileFormat.PPT)
                    && !l_oFileFormat.Equals(Constant.DocumentFileFormat.PPTX))
                {
                    SearchInput.IsEnabled = true;
                    SearchButton.IsEnabled = true;
                }
                else
                {
                    SearchInput.IsEnabled = false;
                    SearchButton.IsEnabled = false;
                    PreviousSearchPage.IsEnabled = false;
                    NextSearchPage.IsEnabled = false;
                }

                if (CurrentDisplayMode == AppDisplayMode.Search)
                {
                    var query = GetDataContext.AddActionHistoricQuery((int)Constant.UserActions.CONSULTATION, 0, 0, null, GetFileNameSelected);
                    GetDataContext.Load(query);
                }

                ClearViewer();

                if (ListAllDocFileName != null && ListAllDocFileName.Count != 0 || !string.IsNullOrEmpty(versionRelativeFilepath))
                {
                    //Notify use of loading
                    Dispatcher.BeginInvoke(() =>
                        {
                            TextBlockMode.Visibility = Visibility.Visible;
                            TextBlockMode.Text = Resx.GetLabel(ResxCommon.LOADING_PAGE);
                        });

                    if (string.IsNullOrEmpty(versionRelativeFilepath))
                    {
                        //Get the last version number 
                        var doc = CurrentDocument;
                        if (doc != null && string.IsNullOrEmpty(p_oVersionNumber) && CurrentDocument.GetLastVersionItem() != null)
                        {
                            p_oVersionNumber = CurrentDocument.GetLastVersionItem().VersionId.ToString();
                        }
                        CallGetDocumentWCFService(p_iStartPage, p_iEndPage, GetFileNameSelected, p_oVersionNumber);
                    }
                    else
                    {
                        CallGetDocumentWCFService(p_iStartPage, p_iEndPage, versionRelativeFilepath, p_oVersionNumber);
                    }

                    // Launch the SplashScreen to wait the response
                    if (p_bDisplaySplashScreen)
                        CursorWait(this);
                }
                else
                {
                    ReinitializeViewer();
                }

            }
            catch (Exception ex)
            {
                Dispatcher.BeginInvoke(() =>
                {
                    TextBlockMode.Visibility = Visibility.Collapsed;
                    TextBlockMode.Text = Resx.GetLabel(ResxCommon.MODE_VIEWER);
                });

                RestoreSelectedDocumentIndex();

                string text = "GetSourceDocument\n\n";
                text += ex.Message;

                MessageBoxChildWindow L_oMessageGetDocument = new MessageBoxChildWindow("", text, MessageBoxButtons.Ok, MessageBoxIcon.Error, true, Logger.Level.Debug, text);
                L_oMessageGetDocument.ShowDialog();
            }
        }

        /// <summary>
        /// This method build the query to call the GetDocumentByFullPath or GetImportDocumentByFileName WCF Service
        /// </summary>
        /// <param name="p_iStartPage"></param>
        /// <param name="p_iEndPage"></param>
        private void CallGetDocumentWCFService(int p_iStartPage, int p_iEndPage, string p_sRelativeFilePath, string p_oVersionNumber = "")
        {
            WCFServiceClient l_oWCFServiceClient = ServiceManager.GetRioWCFServiceClient();

            if (CurrentDisplayMode == AppDisplayMode.Search || CurrentDisplayMode == AppDisplayMode.Flow)
            {
                l_oWCFServiceClient.GetDocumentByFullPathCompleted += L_oWCFServiceClient_GetDocumentByFullPathCompleted;

                l_oWCFServiceClient.GetDocumentByFullPathAsync(
                    Path.Combine(ParameterStorage, p_sRelativeFilePath),
                    p_iStartPage,
                    p_iEndPage, ServiceManager.GetLicenseKey(),
                    false,
                    UserId,
                    p_oVersionNumber,
                    p_iStartPage);
            }
            else
            {
                l_oWCFServiceClient.GetImportDocumentByFileNameCompleted += L_oWCFServiceClient_GetImportDocumentByFileNameCompleted;

                l_oWCFServiceClient.GetImportDocumentByFileNameAsync(
                    p_sRelativeFilePath,
                    UserId,
                    p_iStartPage,
                    p_iEndPage, ServiceManager.GetLicenseKey(),
                    p_iStartPage);

                ManageToolbarState();
            }
        }

        /// <summary>
        /// Retries the get document.
        /// </summary>
        /// <param name="p_iUserState">State of the p_i user.</param>
        /// <param name="p_sErrorMessage">The P_S error message.</param>
        /// <param name="p_bIsGetImportDocumentByFilename">if set to <c>true</c> [P_B is get import document by filename].</param>
        private void RetryGetDocument(int p_iUserState, ErrorCodesEnums.ReturnObjectErrorCodesEnum p_iErrorCode, string p_sErrorMessage, string p_sStackTrace, bool p_bIsGetImportDocumentByFilename)
        {
            int l_iStartPage = p_iUserState;
            if (m_iCallServiceNbAttempt < 49)
            {
                //Wait before retry
                Thread.Sleep(50);

                CallGetDocumentWCFService(l_iStartPage, l_iStartPage, GetFileNameSelected);
                m_iCallServiceNbAttempt++;
            }
            else
            {
                RestoreSelectedDocumentIndex();
                //Logger.Write("EXCEPTION : " + Environment.NewLine + e.Error.Message, Logger.Level.Error);

                string messageDetail = String.Empty;

                if (p_bIsGetImportDocumentByFilename)
                {
                    messageDetail = String.Format("L_oWCFServiceClient_GetImportDocumentByFileNameCompleted\n\n{0}", p_sErrorMessage);
                }
                else
                {
                    messageDetail = String.Format("L_oWCFServiceClient_GetDocumentByFullPathCompleted\nNb tentatives = {0}\n{1}", m_iCallServiceNbAttempt, p_sErrorMessage);
                }

                //Close Splash Screen and waiting cursor
                CursorNormal(this);
                SplashScreenManager.Stop(this);

                //Move to error page
                ErrorPage errorPage = new ErrorPage()
                {
                    ErrorTitle = p_iErrorCode.szGetDescription(),
                    ErrorCode = (int)p_iErrorCode,
                    StackTrace = p_sStackTrace,
                    ErrorMessageDetail = p_sErrorMessage,
                    FriendlyMessage = Resx.GetLabel(ResxCommon.FRIENDLY_MESSAGE),
                    AdministratorEmail = null,
                };

                errorPage.Show();
            }
        }

        /// <summary>
        /// Response for the 'GetSourceDocumentByFileNameAsync' call
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void L_oWCFServiceClient_GetImportDocumentByFileNameCompleted(object sender, GetImportDocumentByFileNameCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                //Try to reconnect
                RetryGetDocument((int)e.UserState, ErrorCodesEnums.ReturnObjectErrorCodesEnum.ServerNotFound, e.Error.Message, e.Error.StackTrace, true);
            }
            else
            {
                ReturnDoubleValue l_oReturnDoubleValue = e.Result;

                bool canContinueProcess = l_oReturnDoubleValue.IsValid;

                if (!l_oReturnDoubleValue.IsValid)
                {
                    ErrorCodesEnums.ReturnObjectErrorCodesEnum errorCode = (ErrorCodesEnums.ReturnObjectErrorCodesEnum)Enum.ToObject(typeof(ErrorCodesEnums.ReturnObjectErrorCodesEnum), l_oReturnDoubleValue.ErrorCode);

                    //Treat error according to its error code
                    switch (errorCode)
                    {
                        case ErrorCodesEnums.ReturnObjectErrorCodesEnum.CorruptedFile:
                            canContinueProcess = true;

                            break;

                        case ErrorCodesEnums.ReturnObjectErrorCodesEnum.FileNotFound:
                            canContinueProcess = false;

                            MessageBoxChildWindow errorMessage = new MessageBoxChildWindow(
                                String.Empty,
                                Resx.GetLabel(ResxCommon.MSG_FILE_NOT_FOUND),
                                MessageBoxButtons.Ok,
                                MessageBoxIcon.Information);

                            errorMessage.ShowDialog();

                            RestoreSelectedDocumentIndex();
                            CursorNormal(this);

                            break;

                        default:
                            //Try to reconnect
                            RetryGetDocument(
                                (int)e.UserState,
                                ErrorCodesEnums.ReturnObjectErrorCodesEnum.ServerNotFound,
                                String.Empty,
                                String.Empty,
                                true);

                            break;
                    }
                }

                if (canContinueProcess)
                {
                    Dispatcher.BeginInvoke(() =>
                    {
                        TextBlockMode.Visibility = Visibility.Collapsed;
                        TextBlockMode.Text = Resx.GetLabel(ResxCommon.MODE_VIEWER);
                    });

                    DisplaySourceDocumentInternal(l_oReturnDoubleValue.Value, l_oReturnDoubleValue.SecondValue);

                    WCFServiceClient L_oWCFServiceClient = ServiceManager.GetRioWCFServiceClient();
                    string l_oFilePath = GetFileNameSelected;
                    if ((int)e.UserState == 1 && Path.GetExtension(l_oFilePath).Equals(Constant.DocumentFileFormat.PDF.szGetDescription(), StringComparison.CurrentCultureIgnoreCase))
                    {

                        L_oWCFServiceClient.GeneratePdfPagesAsync(l_oFilePath, UserId, true, ServiceManager.GetLicenseKey());
                    }

                    m_iCallServiceNbAttempt = 0;

                    ManageToolbarState();
                    CursorNormal(this);
                }
            }
        }

        /// <summary>
        /// Response for the 'GetSourceDocumentByFullPathAsync' call
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void L_oWCFServiceClient_GetDocumentByFullPathCompleted(object sender, GetDocumentByFullPathCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                //Try to reconnect
                RetryGetDocument((int)e.UserState, ErrorCodesEnums.ReturnObjectErrorCodesEnum.ServerNotFound, e.Error.Message, e.Error.StackTrace, false);
            }
            else
            {
                ReturnDoubleValue l_oReturnDoubleValue = e.Result;

                bool canContinueProcess = l_oReturnDoubleValue.IsValid;

                if (!l_oReturnDoubleValue.IsValid)
                {
                    //Treat error according to its error code
                    ErrorCodesEnums.ReturnObjectErrorCodesEnum errorEnum = ErrorCodesEnums.ReturnObjectErrorCodesEnum.UnknowError;
                    Enum.TryParse<ErrorCodesEnums.ReturnObjectErrorCodesEnum>(Convert.ToString(l_oReturnDoubleValue.ErrorCode), out errorEnum);

                    switch (errorEnum)
                    {
                        case ErrorCodesEnums.ReturnObjectErrorCodesEnum.CorruptedFile:
                            //Allow display
                            canContinueProcess = true;
                            break;

                        case ErrorCodesEnums.ReturnObjectErrorCodesEnum.FileNotFound:
                            //Stop SplashScreen
                            CursorNormal(this);

                            //Prompt MessageBox
                            MessageBoxChildWindow errorMessageBox = new MessageBoxChildWindow(
                                String.Empty,
                                errorEnum.szGetDescription(),
                                MessageBoxButtons.Ok,
                                MessageBoxIcon.Error);

                            errorMessageBox.ShowDialog();

                            RestoreSelectedDocumentIndex();

                            break;

                        default:
                            //Try to reconnect
                            RetryGetDocument(
                                (int)e.UserState,
                                errorEnum,
                                l_oReturnDoubleValue.ErrorMessage,
                                l_oReturnDoubleValue.FullErrorMessage,
                                true);

                            break;
                    }
                }

                if (canContinueProcess)
                {
                    Dispatcher.BeginInvoke(() =>
                    {
                        TextBlockMode.Visibility = Visibility.Collapsed;
                        TextBlockMode.Text = Resx.GetLabel(ResxCommon.MODE_VIEWER);
                    });

                    DisplaySourceDocumentInternal(l_oReturnDoubleValue.Value, l_oReturnDoubleValue.SecondValue);

                    WCFServiceClient L_oWCFServiceClient = ServiceManager.GetRioWCFServiceClient();
                    string l_oFilePath = GetFileNameSelected;
                    if (e.UserState != null && (int)e.UserState == 1 && Path.GetExtension(l_oFilePath).Equals(Constant.DocumentFileFormat.PDF.szGetDescription(), StringComparison.CurrentCultureIgnoreCase))
                    {
                        L_oWCFServiceClient.GeneratePdfPagesAsync(Path.Combine(ParameterStorage, l_oFilePath), UserId, false, ServiceManager.GetLicenseKey());
                    }

                    m_iCallServiceNbAttempt = 0;
                    CursorNormal(this);

                    ManageToolbarState();
                }
            }
        }

        /// <summary>
        /// Display the response of 'GetSourceDocument'
        /// </summary>
        /// <param name="p_aRawImage"></param>
        /// <param name="p_iCountPage"></param>
        private void DisplaySourceDocumentInternal(Byte[] p_aRawImage, int p_iCountPage)
        {
            DisplaySourceDocument(p_aRawImage, 0, p_iCountPage);
        }

        /// <summary>
        /// Display the response of 'GetSourceDocument'
        /// </summary>
        /// <param name="p_aRawImage"></param>
        /// <param name="p_iIndexDocument"></param>
        /// <param name="p_iCountPage"></param>
        private void DisplaySourceDocument(Byte[] p_aRawImage, int p_iIndexDocument, int p_iCountPage)
        {
            try
            {
                // Store the buffer image raw
                m_aRawImage = p_aRawImage;

                // Store the number of pages
                m_iNbOfPage = p_iCountPage;

                // Display the image into the viewer
                DisplayImage(m_aRawImage);

                // Display the Normal cursor
                CursorNormal(this);

                // Update the menu for document's navigation
                UpdateNavigationForDocuments();

                // Update the menu for pages's navigation
                UpdateNavigationForPages();

                // raise the event 'OnItemsSelected'
                if (CurrentDisplayMode == AppDisplayMode.Search)
                {
                    //FPE: Change test with identifier
                    m_oCurrentDocument = ListDocument[SelectedDocumentIndex];
                    OnItemsSelected(new List<Document> { m_oCurrentDocument });
                }
                else
                {
                    if (CurrentSelectedImage != null && CurrentSelectedImage.isDirectory)
                        OnDirectorySelected();
                    else
                        OnItemsSelected(new List<string> { GetFileNameSelected });
                }
            }
            catch (Exception)
            {



                //Logger.Write("EXCEPTION :  DisplaySourceDocument " + Environment.NewLine + ex.Message, Logger.Level.Error);

                //if (ListAllDocFileName.Count > 0)
                //{
                //    GetSourceDocument(1, 1);
                //}
            }
        }
        #endregion

        #region Viewer command

        #region Resize

        /// <summary>
        /// Called when [zoom plus click].
        /// </summary>
        private void OnZoomPlusClick()
        {
            // Set the viewer in normal mode
            SetViewerInNormalMode(0.05);
        }

        /// <summary>
        /// Called when [zoom moins click].
        /// </summary>
        private void OnZoomMoinsClick()
        {
            // Set the viewer in normal mode
            SetViewerInNormalMode(-0.05);
        }
        #endregion

        #region Rotates functions

        /// <summary>
        /// Apply a rotation to whole items selected
        /// </summary>
        /// <param name="p_bRotateRight">apply a right rotation otherwise a left one</param>
        private void ApplyRotateMenuClick(bool p_bRotateRight)
        {
            if (ListAllDocFileName != null && ListAllDocFileName.Count > 0)
            {
                string l_sCombinePath = GetFileNameSelected;
                if (CurrentDisplayMode == AppDisplayMode.Search)
                {
                    string l_sThumbnailFullPath = AddThumbnailExtension(Path.Combine(ParameterStorageThumbnail, GetFileNameSelected));
                    l_sCombinePath = string.Format("{0}#{1}", GetFileNameSelected, l_sThumbnailFullPath);
                }
                RotateDocumentWCFServices(DisplaySourceDocument, ParameterStorage, l_sCombinePath, m_aRawImage, p_bRotateRight, SelectedDocumentIndex, IndexPage, false, m_iNbOfPage);
            }
        }

        #endregion

        #region Print

        /// <summary>
        /// Called when [print menu click].
        /// </summary>
        private void OnPrintMenuClick()
        {
            if (ListAllDocFileName != null && ListAllDocFileName.Count > 0)
            {
                PrintDocumentsInPDFFormat(new List<string> { Path.Combine(ParameterStorage, GetFileNameSelected) });
            }
        }

        /// <summary>
        /// Called when [print menu click].
        /// </summary>
        private void OnDocumentPrintMenuClick()
        {
            DocumentPrintArea.Visibility = System.Windows.Visibility.Visible;
            DocumentPrintArea.IsExpanded = true;
        }

        #endregion

        #region Save

        /// <summary>
        /// Saves the modification on image.
        /// </summary>
        /// <param name="p_oCallEventClick">The p_o call event click.</param>
        /// <param name="p_bMergeAfter">The P_B merge after.</param>
        private void SaveModificationOnImage(Rio.Framework.Pages.Viewer.UCViewerCore.ClickEvent p_oCallEventClick, bool p_bMergeAfter)
        {
            if (ListAllDocFileName != null && ListAllDocFileName.Count > 0)
            {
                if (ModifyRotateList.Count != 0)
                {

                    MessageBoxChildWindow l_oMessage = new MessageBoxChildWindow(String.Empty, LabelSaveModificationImage, MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                    l_oMessage.ShowDialog();
                    l_oMessage.Closed += (s, ev) =>
                                             {
                                                 if (l_oMessage.Result == MessageBoxResult.Yes)
                                                 {
                                                     SplashScreenManager.Wait(this);
                                                     WCFServiceClient l_oWCFServiceClient = ServiceManager.GetRioWCFServiceClient();
                                                     if (CurrentDisplayMode == AppDisplayMode.Search)
                                                     {
                                                         l_oWCFServiceClient.SaveRotatedImagesWithFullPathCompleted += l_oWCFServiceClient_SaveRotatedImagesWithFullPathCompleted;
                                                         l_oWCFServiceClient.SaveRotatedImagesWithFullPathAsync(ModifyRotateList, ServiceManager.GetLicenseKey(), UserId, p_oCallEventClick);
                                                     }
                                                     else
                                                     {
                                                         Dictionary<bool, ClickEvent> p = new Dictionary<bool, ClickEvent>();
                                                         p.Add(p_bMergeAfter, p_oCallEventClick);

                                                         l_oWCFServiceClient.SaveImportRotatedImagesWithDirectoryCompleted += l_oWCFServiceClient_SaveImportRotatedImagesCompleted;
                                                         //l_oWCFServiceClient.SaveImportRotatedImagesAsync(ModifyRotateList, UserId, p_oCallEventClick);
                                                         l_oWCFServiceClient.SaveImportRotatedImagesWithDirectoryAsync(ModifyRotateList, UserId, CurrentSelectedDirectory, ServiceManager.GetLicenseKey(), p);
                                                     }
                                                 }
                                                 else
                                                 {
                                                     SaveRotatedImagesCompleted(p_oCallEventClick);
                                                     if (p_bMergeAfter)
                                                         MergeDocumentInPDF();
                                                 }
                                             };
                }
                else
                {
                    SaveRotatedImagesCompleted(p_oCallEventClick);

                    if (p_bMergeAfter)
                        MergeDocumentInPDF();
                }
            }
        }

        /// <summary>
        /// Handles the SaveRotatedImagesWithFullPathCompleted event of the l_oWCFServiceClient control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Rio.Framework.WCFService.RioWcfServices.SaveRotatedImagesWithFullPathCompletedEventArgs" /> instance containing the event data.</param>
        private void l_oWCFServiceClient_SaveRotatedImagesWithFullPathCompleted(object sender, SaveRotatedImagesWithFullPathCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                //Logger.Write("EXCEPTION : " + Environment.NewLine + e.Error.Message, Logger.Level.Error);
                string text = "l_oWCFServiceClient_SaveRotatedImagesWithFullPathCompleted\n\n";
                text += e.Error.Message;
                MessageBoxChildWindow L_oMessageGetDocument = new MessageBoxChildWindow("", text, MessageBoxButtons.Ok, MessageBoxIcon.Error, true, Logger.Level.Debug, text);
                L_oMessageGetDocument.ShowDialog();
            }
            else
            {
                ReturnObject l_oReturn = e.Result;
                if (l_oReturn.IsValid == false)
                {
                    //Logger.Write("NOT VALID : " + Environment.NewLine + l_oReturn.ErrorMessage, Logger.Level.Error);
                    string text = "l_oWCFServiceClient_SaveRotatedImagesWithFullPathCompleted - NOT VALID\n\n";
                    text += e.Error.Message;
                    MessageBoxChildWindow L_oMessageGetDocument = new MessageBoxChildWindow("", text, MessageBoxButtons.Ok, MessageBoxIcon.Error, true, Logger.Level.Debug, text);
                    L_oMessageGetDocument.ShowDialog();
                }
                else
                {
                    SaveRotatedImagesCompleted((ClickEvent)e.UserState);
                }
            }
        }

        /// <summary>
        /// Handles the SaveImportRotatedImagesCompleted event of the l_oWCFServiceClient control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Rio.Framework.WCFService.RioWcfServices.SaveImportRotatedImagesWithDirectoryCompletedEventArgs" /> instance containing the event data.</param>
        private void l_oWCFServiceClient_SaveImportRotatedImagesCompleted(object sender, SaveImportRotatedImagesWithDirectoryCompletedEventArgs e)
        {
            ClickEvent l_oclickEvent;
            bool l_bMergeAfter = false;

            if (e != null && e.Error != null)
            {
                LoggerHelper.Send(this.GetType().Name, e.Error.Message);
            }
            else if (e != null && e.UserState != null)
            {
                Dictionary<bool, ClickEvent> p = (Dictionary<bool, ClickEvent>)e.UserState;
                foreach (bool l_oneBool in p.Keys)
                {
                    l_bMergeAfter = l_oneBool;
                }

                l_oclickEvent = p[l_bMergeAfter];

                ReturnObject l_oReturn = e.Result;
                if (l_oReturn.IsValid == true)
                {
                    if (l_bMergeAfter)
                    {
                        MergeDocumentInPDF();
                    }
                }
                else
                {
                    LoggerHelper.Send(this.GetType().Name, "Return object is not valid");
                }

                //In all case we finalize the action
                SaveRotatedImagesCompleted(l_oclickEvent);
            }
        }

        /// <summary>
        /// Clears the modification.
        /// </summary>
        private void ClearModification()
        {
            ModifyRotateList.Clear();
            DocumentToolbar.SetAvailability(DocumentRibbonBarMenuItems.SaveModifications, SaveModificationEnabled);
            DocumentContextMenu.SetAvailability(DocumentRibbonBarMenuItems.SaveModifications, SaveModificationEnabled);
        }

        /// <summary>
        /// Saves the rotated images completed.
        /// </summary>
        /// <param name="p_iClickEvent">The p_i click event.</param>
        private void SaveRotatedImagesCompleted(ClickEvent p_iClickEvent)
        {
            //Update save modification menus 
            ClearModification();

            switch (p_iClickEvent)
            {
                case ClickEvent.FirstDocumentClick:
                    OnFirstDocumentClick();
                    break;
                case ClickEvent.LastDocumentClick:
                    OnLastDocumentClick();
                    break;
                case ClickEvent.NextDocumentClick:
                    OnNextDocumentClick();
                    break;
                case ClickEvent.PreviousDocumentClick:
                    OnPreviousDocumentClick();
                    break;
                case ClickEvent.FirstPageClick:
                    OnFirstPageClick();
                    break;
                case ClickEvent.LastPageClick:
                    OnLastPageClick();
                    break;
                case ClickEvent.NextPageClick:
                    OnNextPageClick();
                    break;
                case ClickEvent.PreviousPageClick:
                    OnPreviousPageClick();
                    break;
                case ClickEvent.SaveModificationClick:
                    SplashScreenManager.Stop(this);
                    break;
                case ClickEvent.Viewer:
                    OnActivateThumbnailMode();
                    SplashScreenManager.Stop(this);
                    break;
                case ClickEvent.OpenDirectory:
                    OpenDirectoryHandle();
                    break;
                case ClickEvent.ReturnDirectory:
                    ReturnDirectoryHandle();
                    break;
                default:
                    break;
            }

            ManageToolbarState();
        }
        #endregion

        #region Clicks

        /// <summary>
        /// Goes to thumbnail mode.
        /// </summary>
        public void GoToThumbnailMode()
        {
            if (ModifyRotateList.Count != 0
                && (CurrentDisplayMode == AppDisplayMode.Import || CurrentDisplayMode == AppDisplayMode.AddDocument))
            {
                SaveModificationOnImage(ClickEvent.Viewer, false);
            }
            else
            {
                OnActivateThumbnailMode();
            }
        }

        /// <summary>
        /// Goes to list mode.
        /// </summary>
        public void GoToListMode()
        {
            if (ModifyRotateList.Count != 0
                && (CurrentDisplayMode == AppDisplayMode.Import || CurrentDisplayMode == AppDisplayMode.AddDocument))
            {
                SaveModificationOnImage(ClickEvent.Viewer, false);
            }
            else
            {
                OnActivateListMode();
            }
        }

        /// <summary>
        /// Called when [ventil click].
        /// </summary>
        private void OnVentilClick()
        {
            if (ListAllDocFileName != null && ListAllDocFileName.Count > 0)
            {
                Document l_oSelectedDocument = ListDocument.Where(f => f.ImageName == Path.GetFileName(GetFileNameSelected)).FirstOrDefault();

                List<long> l_oDocumentListToVentil = new List<long>();
                l_oDocumentListToVentil.Add(l_oSelectedDocument.Identifier);
                VentilateWindow l_oVentilWindow = new VentilateWindow(l_oDocumentListToVentil, 0, UserId, string.Empty);
                l_oVentilWindow.ShowDialog();
            }
        }

        /// <summary>
        /// Called when [save document click].
        /// </summary>
        private void OnSaveDocumentClick()
        {
            try
            {
                if (!String.IsNullOrEmpty(GetFileNameSelected))
                {
                    Document l_oSelectedDocument = ListDocument.Where(f => f.ImageName == Path.GetFileName(GetFileNameSelected)).FirstOrDefault();

                    if (CurrentDisplayMode == AppDisplayMode.Search)
                    {
                        BusinessEntitiesDomainContext l_oBecDC = new BusinessEntitiesDomainContext();
                        var query = l_oBecDC.AddActionHistoricQuery((int)Constant.UserActions.TELECHARGEMENT, 0, 0, null, l_oSelectedDocument.ImageName);
                        l_oBecDC.Load(query);
                    }

                    //Build URI
                    WebClient webClient = new WebClient();
                    Uri baseUri = new Uri(webClient.BaseAddress);
                    UriBuilder uriBuilder = new UriBuilder(baseUri.Scheme, baseUri.Host, baseUri.Port);

                    string path = uriBuilder.ToString().TrimEnd('/');
                    string filename = "/Rio.Application.FileDownload.aspx?fp=" + Path.Combine(ParameterStorage, GetFileNameSelected) + "&name=" + l_oSelectedDocument.OriginalNameFile;

                    VariableDomainContext L_vdcAppVirtualPath = new VariableDomainContext();
                    L_vdcAppVirtualPath.GetAppDomainAppVirtualPath(delegate(InvokeOperation<string> str)
                    {
                        if (str.Value == "/")
                        {
                            System.Windows.Browser.HtmlPage.Window.Navigate(new Uri(path + filename, UriKind.Absolute));
                        }
                        else
                        {
                            System.Windows.Browser.HtmlPage.Window.Navigate(new Uri(path + str.Value + filename, UriKind.Absolute));
                        }
                    }
                    , null);
                }
            }
            catch (Exception)
            {
                //Logger.Write("EXCEPTION : " + Environment.NewLine + ex.Message, Logger.Level.Error);
            }
        }

        #endregion

        #region Send Mail

        /// <summary>
        /// Called when [send mail click].
        /// </summary>
        private void OnSendMailClick()
        {
            if (ListAllDocFileName != null && ListAllDocFileName.Count > 0)
            {
                if (GetFileNameSelected != null && !String.Empty.Equals(GetFileNameSelected))
                {
                    Document l_oSelectedDocument = ListDocument.Where(f => f.ImageName == Path.GetFileName(GetFileNameSelected)).FirstOrDefault();
                    List<Document> l_oDocumentList = new List<Document>();
                    l_oDocumentList.Add(l_oSelectedDocument);
                    EmailWindow l_oEmailWindow = new EmailWindow(m_oCurrentOrganization, l_oDocumentList, ParameterStorage);
                    l_oEmailWindow.ShowDialog();
                }
            }
        }

        #endregion

        #region Copy-Cut-Paste

        /// <summary>
        /// Return a ImageRioSearch list from the selected thumbnails
        /// </summary>
        /// <returns>List of identifiers</returns>
        protected override List<long> GetListIdentifierToCopy()
        {
            List<long> resultList = new List<long>();
            if (ListAllDocFileName != null && ListAllDocFileName.Count > 0)
            {
                if (CurrentDisplayMode == AppDisplayMode.Search || CurrentDisplayMode == AppDisplayMode.Flow)
                {
                    resultList = new List<long>() 
                    { 
                        ListDocument.Where(item => item.ImageName.Equals(Path.GetFileName(GetFileNameSelected))).FirstOrDefault().Identifier
                    };
                }
            }
            return resultList;
        }

        #endregion

        #region Delete items

        /// <summary>
        /// Called when [item delete click].
        /// </summary>
        private void OnItemDeleteClick()
        {
            if (ListAllDocFileName != null && ListAllDocFileName.Count > 0)
            {
                if (CurrentDisplayMode == AppDisplayMode.Search)
                {
                    if (ListDocument != null)
                    {
                        RemoveOrDeleteSelectedDocuments(
                            ListDocument.Where(item => item.ImageName.Equals(Path.GetFileName(GetFileNameSelected))).
                                Select(item => item.Identifier).ToList(),
                            OnDeleteDocumentQueryCallback);
                    }
                }
                else
                {
                    //Delete an imported document
                    if (CurrentSelectedImage != null)
                    {
                        MessageBoxChildWindow L_oMessage = new MessageBoxChildWindow(String.Empty, LabelDeleteThumbnail, MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                        L_oMessage.ShowDialog();
                        L_oMessage.Closed += (s, ev) =>
                        {
                            if (L_oMessage.Result == MessageBoxResult.Yes)
                            {
                                //Launch SplashScreen
                                SplashScreenManager.Wait(this);
                                CursorWait(this);

                                BusinessEntitiesDomainContext l_oBecDC = new BusinessEntitiesDomainContext();
                                var query = l_oBecDC.AddActionHistoricQuery((int)Constant.UserActions.SUPPRESSION_IMAGE, 0, 0, null, CurrentSelectedImage.Name.ToString(";"));
                                l_oBecDC.Load(query);

                                WCFServiceClient L_oWCFServiceClient = ServiceManager.GetRioWCFServiceClient();
                                L_oWCFServiceClient.DeleteImportImagesCompleted += L_oWCFServiceClient_DeleteImportImagesCompleted;
                                L_oWCFServiceClient.DeleteImportImagesAsync(new ObservableCollection<ImageRio>() { CurrentSelectedImage }, UserId, ServiceManager.GetLicenseKey(), CurrentSelectedImage);

                            }
                        };
                    }
                }
            }
        }

        /// <summary>
        /// Handles the DeleteImportImagesCompleted event of the L_oWCFServiceClient control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Rio.Framework.WCFService.RioWcfServices.DeleteImportImagesCompletedEventArgs" /> instance containing the event data.</param>
        private void L_oWCFServiceClient_DeleteImportImagesCompleted(object sender, DeleteImportImagesCompletedEventArgs e)
        {
            if (e == null || e.Error == null)
            {
                DeleteDocumentSuccessful(e.UserState as ImageRio);
            }
        }

        /// <summary>
        /// Called when [delete document query callback].
        /// </summary>
        /// <param name="result">The result.</param>
        private void OnDeleteDocumentQueryCallback(LoadOperation<NetBay.Core.BusinessEntities.ReturnObject> result)
        {
            if (result.Error == null)
            {
                DeleteDocumentSuccessful();
            }
        }

        /// <summary>
        /// Deletes the document successful.
        /// </summary>
        private void DeleteDocumentSuccessful(ImageRio deletedImage = null)
        {
            string l_oSelectedFileNameToRemove = GetFileNameSelected;

            // Remove selectedFileName
            ListAllDocFileName.Remove(l_oSelectedFileNameToRemove);

            if (SelectedDocumentIndex >= 1)
            {
                SelectedDocumentIndex--;
            }

            if (CurrentDisplayMode == AppDisplayMode.Search)
            {
                Document L_oDeletededDocument = ListDocument.Where(f => f.ImageName == Path.GetFileName(l_oSelectedFileNameToRemove)).FirstOrDefault();
                ListDocument.Remove(L_oDeletededDocument);
                OnItemsDeletedToRemove(new List<Document> { L_oDeletededDocument });
            }
            else
            {
                OnImportedDocumentDeleted(deletedImage);
            }

            if (ListAllDocFileName.Count > 0)
            {
                TextBlockMode.Visibility = System.Windows.Visibility.Collapsed;
                GetFileNameSelected = ListAllDocFileName.First();
                GetSourceDocument(1, 1);
            }
            else
            {
                TextBlockMode.Visibility = System.Windows.Visibility.Visible;
                ReinitializeViewer();
            }

            //Stop SplashScreen
            CursorNormal(this);
            SplashScreenManager.Stop(this);
        }

        #endregion

        /// <summary>
        /// Sets the viewer in fit mode.
        /// </summary>
        /// <param name="inFitHeight">Height of the in fit.</param>
        private void SetViewerInFitMode(bool inFitHeight = true, double scale = 1.0)
        {
            double l_dRatio = 1;

            //Apply dafeult scale
            if (scale == 0.0)
                scale = 1.0;


            try
            {
                //no image 
                if (ImageViewer == null || ImageViewer.Viewer.Image == null)
                    return;

                if (!inFitHeight)
                {
                    /*
                     * Fit Width
                     */

                    //[0] = New value ; [1]= Old value
                    m_iImageViewWidth[1] = m_iImageViewWidth[0];

                    if (ImageViewer.ActualWidth != 0)
                    {
                        m_iImageViewWidth[0] = ImageViewer.ActualWidth;

                        l_dRatio = Math.Round(m_iImageViewWidth[0] / ImageViewer.Viewer.Image.Width, 1);

                        if (l_dRatio < 1)
                        {
                            ImageViewer.Viewer.ScaleFactor = (l_dRatio * scale) - 0.05;
                        }
                        else
                        {
                            ImageViewer.Viewer.ScaleFactor = 1.0;
                        }
                    }
                    else
                    {
                        ImageViewer.Viewer.ScaleFactor = 1.0;
                    }
                }
                else
                {
                    /*
                     * Fit Height
                     */

                    //[0] = New value ; [1]= Old value
                    m_iImageViewHeight[1] = m_iImageViewHeight[0];

                    if (ImageViewer.ActualHeight != 0)
                    {
                        m_iImageViewHeight[0] = ImageViewer.ActualHeight;

                        l_dRatio = Math.Round(m_iImageViewHeight[0] / ImageViewer.Viewer.Image.Height, 1);

                        if (l_dRatio < 1)
                        {
                            ImageViewer.Viewer.ScaleFactor = (l_dRatio * scale) - 0.05;
                        }
                        else
                        {
                            ImageViewer.Viewer.ScaleFactor = 1.0;
                        }
                    }
                    else
                    {
                        ImageViewer.Viewer.ScaleFactor = 1.0;
                    }
                }

                IsInFitHeightMode = inFitHeight;
            }
            catch (Exception e)
            {
                LoggerHelper.Send(this.GetType().Name, String.Format("[inFitHeight = {0} ] - {1}", inFitHeight, e.Message));

                if (!inFitHeight)
                {
                    //In case of trouble we apply the old value
                    m_iImageViewWidth[0] = m_iImageViewWidth[1];

                    l_dRatio = Math.Round(m_iImageViewWidth[0] / ImageViewer.Viewer.Image.Width, 1);
                }
                else
                {
                    //In case of trouble we apply the old value
                    m_iImageViewHeight[0] = m_iImageViewHeight[1];

                    l_dRatio = Math.Round(m_iImageViewHeight[0] / ImageViewer.Viewer.Image.Height, 1);
                }

                if (l_dRatio < 1)
                {
                    ImageViewer.Viewer.ScaleFactor = l_dRatio - 0.05;
                }
                else
                {
                    ImageViewer.Viewer.ScaleFactor = 1.0;
                }

                if (ListAllDocFileName != null && ListAllDocFileName.Count > 0)
                {
                    GetSourceDocument(1, 1);
                }
            }
        }

        /// <summary>
        /// Set the viewer in normal mode
        /// </summary>
        /// <param name="p_dAddScaleFactor">The P_D add scale factor.</param>
        private void SetViewerInNormalMode(double p_dAddScaleFactor)
        {
            if (
                (ImageViewer != null) &&
                (ImageViewer.Viewer.Image != null)
                )
            {
                //Put the viewer in normal mode which enables to change the scale
                ImageViewer.Viewer.ScaleFactor = Math.Min(Math.Max(0.1, ImageViewer.Viewer.ScaleFactor + p_dAddScaleFactor), 4);

                double test = ImageViewer.ActualWidth;

                if (ImageViewer.Viewer.ScaleFactor == 0.1)
                {
                    DocumentToolbar.SetAvailability(DocumentRibbonBarMenuItems.ZoomOut, false);
                    DocumentContextMenu.SetAvailability(DocumentRibbonBarMenuItems.ZoomOut, false);
                }
                else
                {
                    if (Convert.ToUInt16(ImageViewer.Viewer.ScaleFactor) == 4)
                    {
                        DocumentToolbar.SetAvailability(DocumentRibbonBarMenuItems.ZoomIn, false);
                        DocumentContextMenu.SetAvailability(DocumentRibbonBarMenuItems.ZoomIn, false);
                    }
                    else
                    {
                        DocumentToolbar.SetAvailability(DocumentRibbonBarMenuItems.ZoomIn, true);
                        DocumentContextMenu.SetAvailability(DocumentRibbonBarMenuItems.ZoomIn, true);
                    }
                    DocumentToolbar.SetAvailability(DocumentRibbonBarMenuItems.ZoomOut, true);
                    DocumentContextMenu.SetAvailability(DocumentRibbonBarMenuItems.ZoomOut, true);
                }
            }
        }

        /// <summary>
        /// Display the image into the viewer
        /// </summary>
        /// <param name="p_aImage">Raw image</param>
        private void DisplayImage(Byte[] p_aImage)
        {
            BitmapImage image = new BitmapImage();
            try
            {
                using (MemoryStream stream = new MemoryStream(p_aImage))
                {
                    image = new BitmapImage();
                    image.SetSource(stream);  //May throw an exception (internal error with H_Result)
                }

                m_biImageViewer = image;
                ImageViewer.Viewer.Image = new RadBitmap(m_biImageViewer);

            }
            catch (Exception ex)
            {
                LoggerHelper.Send("CLIENT ERROR ->" + this.GetType().Name + "DisplayImage [image.SetSource(stream)]", ex.Message);

                //If original image load fail then load error image according to current 
                Uri errorImageUri = new Uri(
                    String.Format("/Rio.Framework.Pages;component/Assets/Images/Error/error_{0}.jpg", Thread.CurrentThread.CurrentCulture.Name),
                    UriKind.Relative);

                //Load image from resources
                StreamResourceInfo errorImageStream = Application.GetResourceStream(errorImageUri);
                if (errorImageStream == null)
                {
                    //The error image for current culture doesn't exist
                    Uri errorImageDefaultUri = new Uri("/Rio.Framework.Pages;component/Assets/Images/Error/error_fr-FR.jpg", UriKind.Relative);

                    //Load default image
                    errorImageStream = Application.GetResourceStream(errorImageDefaultUri);
                }

                image.SetSource(errorImageStream.Stream);
                m_biImageViewer = image;
                ImageViewer.Viewer.Image = new RadBitmap(m_biImageViewer);
            }

            ApplyViewerSettings();
        }

        /// <summary>
        /// Clear the Viewer
        /// </summary>
        public void ClearViewer()
        {
            ImageViewer.Viewer.Image = null;
        }

        /// <summary>
        /// Reinitialize the Viewer
        /// </summary>
        public void ReinitializeViewer()
        {
            ClearViewer();
            SelectedDocumentIndex = -1;
            m_iNbOfPage = 0;
            ListAllDocFileName.Clear();
            UpdateNavigationForDocuments();
            UpdateNavigationForPages();
            TextBlockMode.Visibility = System.Windows.Visibility.Visible;
        }

        /// <summary>
        /// Loads the general settings.
        /// </summary>
        private void LoadGeneralSettings()
        {
            _defaultFitToHeight = GlobalWebContext.CurrentUser.CTX_FitToheight;
            _defaultZoomStep = GlobalWebContext.CurrentUser.CTX_ZoomStep;
        }

        /// <summary>
        /// Applies the viewer settings.
        /// </summary>
        private void ApplyViewerSettings()
        {
            IsInFitHeightMode = _defaultFitToHeight;
            SetViewerInFitMode(IsInFitHeightMode, _defaultZoomStep);
        }

        #endregion

        #region Private
        /// <summary>
        /// Restores the index of the selected document.
        /// </summary>
        private void RestoreSelectedDocumentIndex()
        {
            SelectedDocumentIndex = OldSelectedDocumentIndex;
            UpdateNavigationForDocuments();
        }



        /// <summary>
        /// Changes the display mode.
        /// </summary>
        /// <param name="p_oDisplayModeMode">The p_o display mode mode.</param>
        public void ChangeDisplayMode(AppDisplayMode p_oDisplayModeMode)
        {
            CurrentDisplayMode = p_oDisplayModeMode;

            switch (CurrentDisplayMode)
            {
                case AppDisplayMode.Search:
                    DocumentToolbar.AppDisplayMode = AppCode.Enums.AppDisplayMode.Search;
                    DocumentContextMenu.AppDisplayMode = AppCode.Enums.AppDisplayMode.Search;
                    break;
                case AppDisplayMode.Import:
                    DocumentToolbar.AppDisplayMode = AppCode.Enums.AppDisplayMode.Import;
                    DocumentContextMenu.AppDisplayMode = AppCode.Enums.AppDisplayMode.Import;
                    break;
                case AppDisplayMode.Flow:
                    DocumentToolbar.AppDisplayMode = AppCode.Enums.AppDisplayMode.Flow;
                    DocumentContextMenu.AppDisplayMode = AppCode.Enums.AppDisplayMode.Flow;
                    break;
            }
        }


        /// <summary>
        /// Determines whether this instance [can rotate all files].
        /// </summary>
        private void CanRotateAllFiles()
        {
            if (Path.GetExtension(GetFileNameSelected).ToLower() == Constant.DocumentFileFormat.DOC.szGetDescription()
            || Path.GetExtension(GetFileNameSelected).ToLower() == Constant.DocumentFileFormat.DOCX.szGetDescription()
            || Path.GetExtension(GetFileNameSelected).ToLower() == Constant.DocumentFileFormat.PPT.szGetDescription()
            || Path.GetExtension(GetFileNameSelected).ToLower() == Constant.DocumentFileFormat.PPTX.szGetDescription()
            || Path.GetExtension(GetFileNameSelected).ToLower() == Constant.DocumentFileFormat.RTF.szGetDescription()
            || Path.GetExtension(GetFileNameSelected).ToLower() == Constant.DocumentFileFormat.TXT.szGetDescription()
            || Path.GetExtension(GetFileNameSelected).ToLower() == Constant.DocumentFileFormat.XLS.szGetDescription()
            || Path.GetExtension(GetFileNameSelected).ToLower() == Constant.DocumentFileFormat.XLSX.szGetDescription()
            )
            {
                MessageBoxChildWindow L_oMessageGetDocument = new MessageBoxChildWindow("", LabelRotateUnsupportedFile, MessageBoxButtons.Ok, MessageBoxIcon.Information);
                L_oMessageGetDocument.ShowDialog();
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="p_oImageRioCollection"></param>
        private void UCViewer_ImportedDocumentRefreshed(ObservableCollection<ImageRio> p_oImageRioCollection)
        {
            TextBlockMode.Visibility = System.Windows.Visibility.Collapsed;
            ManageDocumentListRank(p_oImageRioCollection);
            if (ListAllDocFileName != null && ListAllDocFileName.Count > 0)
                GetFileNameSelected = ListAllDocFileName.First();
            else
                GetFileNameSelected = string.Empty;
            GetSourceDocument(1, 1);
            CursorNormal(this);
        }

        /// <summary>
        /// Refreshes the items.
        /// </summary>
        public void RefreshItems(bool ShowWaitMessage = true)
        {
            if (ShowWaitMessage)
                CursorWait(this);
            ImportedDocumentRefreshed += UCViewer_ImportedDocumentRefreshed;
            RefreshImportedDocuments();
        }

        /// <summary>
        /// Manage visibility of current action
        /// </summary>
        public sealed override void ManageToolbarState()
        {
            if (string.IsNullOrEmpty(GetFileNameSelected))
            {
                DocumentContextMenu.ChangeAppDisplayMode(AppDisplayMode.None);
                DocumentToolbar.ChangeAppDisplayMode(AppDisplayMode.None);
            }
            else
            {
                DocumentToolbar.SelectedDocumentCount = 1;
                DocumentContextMenu.SelectedDocumentCount = 1;

                DocumentContextMenu.ChangeAppDisplayMode(CurrentDisplayMode);
                DocumentToolbar.ChangeAppDisplayMode(CurrentDisplayMode);

                if (isOldVersionDisplayed)
                {
                    UpdateNavigationForDocuments();
                }
                else
                {

                    //Only in search mode
                    if (CurrentDisplayMode == AppDisplayMode.Search)
                    {
                        //Copy - Cut menu is enabled only if the selected version is the original version
                        DocumentToolbar.SetAvailability(DocumentRibbonBarMenuItems.Cut,
                                                        this.displayedVersion == null ||
                                                        displayedVersion.IsOriginalVersion);
                        DocumentToolbar.SetAvailability(DocumentRibbonBarMenuItems.Copy,
                                                        this.displayedVersion == null ||
                                                        displayedVersion.IsOriginalVersion);

                        //Copy - Cut menu is enabled only if the selected version is the original version
                        DocumentContextMenu.SetAvailability(DocumentRibbonBarMenuItems.Cut,
                                                            this.displayedVersion == null ||
                                                            displayedVersion.IsOriginalVersion);
                        DocumentContextMenu.SetAvailability(DocumentRibbonBarMenuItems.Copy,
                                                            this.displayedVersion == null ||
                                                            displayedVersion.IsOriginalVersion);

                        //Versionning function
                        DocumentContextMenu.SetAvailability(DocumentRibbonBarMenuItems.MakeToMajorVersion, false);

                        if (CurrentDocument.CurrentModelVersion == null ||
                            CurrentDocument.CurrentModelVersion.ModelType == NetBay.Core.BusinessEntities.Versioning.VersionType.None)
                        {
                            DocumentToolbar.SetAvailability(DocumentRibbonBarMenuItems.CheckOut, false);
                            DocumentToolbar.SetAvailability(DocumentRibbonBarMenuItems.CheckIn, false);
                        }
                    }

                    //Manage visibility of other actions
                    if (CurrentSelectedImage != null)
                    {
                        /*
                         * Toolbar
                         */

                        DocumentToolbar.SetAvailability(DocumentRibbonBarMenuItems.OpenDirectory,
                                                        CurrentSelectedImage.isDirectory);
                        DocumentToolbar.SetAvailability(DocumentRibbonBarMenuItems.RotateLeft,
                                                        !CurrentSelectedImage.isDirectory);
                        DocumentToolbar.SetAvailability(DocumentRibbonBarMenuItems.RotateRight,
                                                        !CurrentSelectedImage.isDirectory);
                        DocumentToolbar.SetAvailability(DocumentRibbonBarMenuItems.SaveModifications,
                                                        !CurrentSelectedImage.isDirectory);
                        DocumentToolbar.SetAvailability(DocumentRibbonBarMenuItems.MergePDF,
                                                        !CurrentSelectedImage.isDirectory);
                        DocumentToolbar.SetAvailability(DocumentRibbonBarMenuItems.SplitPDF,
                                                        !CurrentSelectedImage.isDirectory);

                        /*
                         * Context Menu
                         */

                        DocumentContextMenu.SetAvailability(DocumentRibbonBarMenuItems.OpenDirectory,
                                                            CurrentSelectedImage.isDirectory);
                        DocumentContextMenu.SetAvailability(DocumentRibbonBarMenuItems.RotateLeft,
                                                            !CurrentSelectedImage.isDirectory);
                        DocumentContextMenu.SetAvailability(DocumentRibbonBarMenuItems.RotateRight,
                                                            !CurrentSelectedImage.isDirectory);
                        DocumentContextMenu.SetAvailability(DocumentRibbonBarMenuItems.SaveModifications,
                                                            !CurrentSelectedImage.isDirectory);
                        DocumentContextMenu.SetAvailability(DocumentRibbonBarMenuItems.MergePDF,
                                                            !CurrentSelectedImage.isDirectory);
                        DocumentContextMenu.SetAvailability(DocumentRibbonBarMenuItems.SplitPDF,
                                                            !CurrentSelectedImage.isDirectory);
                    }
                    else
                    {
                        DocumentContextMenu.SetAvailability(DocumentRibbonBarMenuItems.OpenDirectory, false);
                        DocumentToolbar.SetAvailability(DocumentRibbonBarMenuItems.OpenDirectory, false);
                    }

                    //Only in import or add document mode
                    if (CurrentDisplayMode == AppDisplayMode.Import || CurrentDisplayMode == AppDisplayMode.AddDocument)
                    {
                        // Set split visibility 
                        List<string> L_oListExtension = new List<string>();
                        L_oListExtension.AddRange(
                            EnumHelper.GetValues(typeof(Constant.ImageFileFormat)).Cast<Enum>().Select(
                                item => item.szGetDescription()));

                        string extension = Path.GetExtension(GetFileNameSelected);
                        if (extension != null)
                        {
                            string extention = extension.ToLowerInvariant();
                            DocumentContextMenu.SetAvailability(DocumentRibbonBarMenuItems.Split2,
                                                                L_oListExtension.Contains(extention));
                            DocumentContextMenu.SetAvailability(DocumentRibbonBarMenuItems.Split3,
                                                                L_oListExtension.Contains(extention));

                            //Set PDF visibility
                            if (!string.IsNullOrEmpty(GetFileNameSelected) && extention.ToLowerInvariant() == ".pdf"
                                ||
                                !string.IsNullOrEmpty(versionRelativeFilepath) && extention.ToLowerInvariant() == ".pdf")
                            {
                                DocumentToolbar.SetAvailability(DocumentRibbonBarMenuItems.MergePDF, false, true);
                                DocumentContextMenu.SetAvailability(DocumentRibbonBarMenuItems.MergePDF, false, true);

                                DocumentToolbar.SetAvailability(DocumentRibbonBarMenuItems.SplitPDF, true, true);
                                DocumentContextMenu.SetAvailability(DocumentRibbonBarMenuItems.SplitPDF, true, true);
                            }
                            else
                            {
                                DocumentToolbar.SetAvailability(DocumentRibbonBarMenuItems.MergePDF, true);
                                DocumentContextMenu.SetAvailability(DocumentRibbonBarMenuItems.MergePDF, true);

                                DocumentToolbar.SetAvailability(DocumentRibbonBarMenuItems.SplitPDF, false);
                                DocumentContextMenu.SetAvailability(DocumentRibbonBarMenuItems.SplitPDF, false);
                            }
                        }
                    }

                    //Only if defined
                    DocumentToolbar.SetAvailability(DocumentRibbonBarMenuItems.SaveModifications,
                                                    SaveModificationEnabled);
                    DocumentContextMenu.SetAvailability(DocumentRibbonBarMenuItems.SaveModifications,
                                                        SaveModificationEnabled);
                    DocumentToolbar.SetAvailability(DocumentRibbonBarMenuItems.ReturnDirectory,
                                                    !string.IsNullOrEmpty(CurrentSelectedDirectory));
                }
            }
        }

        /// <summary>
        /// Enables the disable menu.
        /// </summary>
        private void EnableDisableMenu()
        {

            ManageToolbarState();

            if (GetFileNameSelected != null)
            {
                string extension = Path.GetExtension(GetFileNameSelected);
                if (extension != null && (extension.Equals(Constant.DocumentFileFormat.DOC.szGetDescription(), StringComparison.CurrentCultureIgnoreCase)
                                                                       || extension.Equals(Constant.DocumentFileFormat.DOCX.szGetDescription(), StringComparison.CurrentCultureIgnoreCase)
                                                                       || extension.Equals(Constant.DocumentFileFormat.PPT.szGetDescription(), StringComparison.CurrentCultureIgnoreCase)
                                                                       || extension.Equals(Constant.DocumentFileFormat.PPTX.szGetDescription(), StringComparison.CurrentCultureIgnoreCase)
                                                                       || extension.Equals(Constant.DocumentFileFormat.RTF.szGetDescription(), StringComparison.CurrentCultureIgnoreCase)
                                                                       || extension.Equals(Constant.DocumentFileFormat.TXT.szGetDescription(), StringComparison.CurrentCultureIgnoreCase)
                                                                       || extension.Equals(Constant.DocumentFileFormat.XLS.szGetDescription(), StringComparison.CurrentCultureIgnoreCase)
                                                                       || extension.Equals(Constant.DocumentFileFormat.XLSX.szGetDescription(), StringComparison.CurrentCultureIgnoreCase))
                    )
                {
                    DocumentToolbar.SetAvailability(DocumentRibbonBarMenuItems.RotateRight, false);
                    DocumentToolbar.SetAvailability(DocumentRibbonBarMenuItems.RotateLeft, false);
                    DocumentContextMenu.SetAvailability(DocumentRibbonBarMenuItems.RotateRight, false);
                    DocumentContextMenu.SetAvailability(DocumentRibbonBarMenuItems.RotateLeft, false);
                }
                else
                {
                    DocumentToolbar.SetAvailability(DocumentRibbonBarMenuItems.RotateRight, true);
                    DocumentToolbar.SetAvailability(DocumentRibbonBarMenuItems.RotateLeft, true);
                    DocumentContextMenu.SetAvailability(DocumentRibbonBarMenuItems.RotateRight, true);
                    DocumentContextMenu.SetAvailability(DocumentRibbonBarMenuItems.RotateLeft, true);
                }
            }
        }

        /// <summary>
        /// Handles the Loaded event of the UCViewerCore control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs" /> instance containing the event data.</param>
        private void UCViewerCore_Loaded(object sender, RoutedEventArgs e)
        {
            ImageViewer.Focus();
            FireOnInitialisationCompleted();
        }

        /// <summary>
        /// Return a list of selected ImageRio in Viewer
        /// </summary>
        /// <returns></returns>
        public override List<T> GetSelectedImage<T>()
        {
            List<T> L_oSelectedItems = new List<T>();
            if (CurrentSelectedImage != null)
            {
                L_oSelectedItems.Add((T)Convert.ChangeType(CurrentSelectedImage, typeof(T), null));
            }
            return L_oSelectedItems;
        }

        #endregion

        #region MergePDF

        /// <summary>
        /// Merges the document in PDF.
        /// </summary>
        private new void MergeDocumentInPDF()
        {
            //Merge PDF is available only in import mode on a non-pdf page
            if (GetFileNameSelected != null
                && Path.GetExtension(GetFileNameSelected).ToLower() != ".pdf"
                && CurrentDisplayMode != AppDisplayMode.Search)
            {
                MessageBoxChildWindow L_oMessagesMergePdf = new MessageBoxChildWindow(String.Empty, LabelMergePdfQuestion, MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                L_oMessagesMergePdf.ShowDialog();

                L_oMessagesMergePdf.Closed += (s, ev) =>
                {
                    if (L_oMessagesMergePdf.Result == MessageBoxResult.Yes)
                    {
                        CursorWait(this);
                        SplashScreenManager.SplashScreen.Message = Resx.GetLabel(ResxCommon.MSG_PREPARE_CONVERT);

                        //This is a new converting, so we generate a new Guid
                        m_oGuidSessionToConvert = Guid.NewGuid();

                        //call WCF to prepare converting
                        WCFServiceClient L_oWCFServiceClient = ServiceManager.GetRioWCFServiceClient();
                        L_oWCFServiceClient.CreateTemporaryDirectoryCompleted += L_oWCFServiceClient_CreateTemporaryDirectoryCompleted;
                        L_oWCFServiceClient.CreateTemporaryDirectoryAsync(m_oGuidSessionToConvert.ToString("N"), ServiceManager.GetLicenseKey());
                    }
                    else
                    {
                        CursorNormal(this);
                    }
                };
            }
        }

        /// <summary>
        /// Handles the CreateTemporaryDirectoryCompleted event of the L_oWCFServiceClient control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Rio.Framework.WCFService.RioWcfServices.CreateTemporaryDirectoryCompletedEventArgs" /> instance containing the event data.</param>
        private void L_oWCFServiceClient_CreateTemporaryDirectoryCompleted(object sender, CreateTemporaryDirectoryCompletedEventArgs e)
        {
            //Clean and prepare objects to converting
            m_oFilenamesToConvert.Clear();
            m_iCurrentIndextoFilenamesToConvert = 0;

            if (e.Result.IsValid)
            {
                //Retry selected documents according to allowed extensions
                if (GetSelectedFilesNameToMergeInPDF(m_oFilenamesToConvert))
                {
                    SplashScreenManager.SplashScreen.Message = Resx.GetLabel(ResxCommon.MSG_CONVERTING);
                    SplashScreenManager.SplashScreen.MessageDetail = m_oFilenamesToConvert[m_iCurrentIndextoFilenamesToConvert];

                    //Initialize pogress bar
                    SplashScreenManager.SplashScreen.ProgressBarProcess.Visibility = System.Windows.Visibility.Visible;
                    SplashScreenManager.SplashScreen.ProgressBarProcess.Minimum = 0;
                    SplashScreenManager.SplashScreen.ProgressBarProcess.Maximum = m_oFilenamesToConvert.Count;
                    SplashScreenManager.SplashScreen.ProgressBarProcess.Value = 0;

                    //Launch converting
                    WCFServiceClient L_oWCFServiceClient = ServiceManager.GetRioWCFServiceClient();
                    L_oWCFServiceClient.ConvertDocumentAppendCompleted += L_oWCFServiceClient_ConvertDocumentAppendCompleted;
                    L_oWCFServiceClient.ConvertDocumentAppendAsync(m_oGuidSessionToConvert.ToString("N"), m_oFilenamesToConvert[m_iCurrentIndextoFilenamesToConvert], UserId, ServiceManager.GetLicenseKey(), true);
                }
            }
            else
            {
                CursorNormal(this);
            }
        }

        /// <summary>
        /// Handles the ConvertDocumentAppendCompleted event of the L_oWCFServiceClient control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Rio.Framework.WCFService.RioWcfServices.ConvertDocumentAppendCompletedEventArgs" /> instance containing the event data.</param>
        private void L_oWCFServiceClient_ConvertDocumentAppendCompleted(object sender, ConvertDocumentAppendCompletedEventArgs e)
        {
            WCFServiceClient L_oWCFServiceClient = ServiceManager.GetRioWCFServiceClient();

            if (e.Result.IsValid)
            {
                ConvertNextDocument(L_oWCFServiceClient);
            }
            else
            {
                //Treat error
                MessageBoxChildWindow errorMessageBox = new MessageBoxChildWindow(
                    String.Empty,
                    String.Format(Resx.GetLabel(ResxCommon.FORMAT_ERROR_WHILE_PROCESSING), m_oFilenamesToConvert[m_iCurrentIndextoFilenamesToConvert]),
                    MessageBoxButtons.YesNo,
                    MessageBoxIcon.Question);

                errorMessageBox.ShowDialog();
                errorMessageBox.Closed += (s, ev) =>
                {
                    if (errorMessageBox.DialogResult == true)
                    {
                        //Delete error document from files to convert to avoid deleting at finish
                        m_oFilenamesToConvert.RemoveAt(m_iCurrentIndextoFilenamesToConvert);

                        //Skip & continue transfert
                        ConvertNextDocument(L_oWCFServiceClient);
                    }
                    else
                    {
                        AbortMergePdf(L_oWCFServiceClient);
                    }
                };
            }
        }

        /// <summary>
        /// Aborts the merge PDF.
        /// </summary>
        /// <param name="L_oWCFServiceClient">The l_o WCF service client.</param>
        private void AbortMergePdf(WCFServiceClient L_oWCFServiceClient)
        {
            //Delete Temporary directory
            L_oWCFServiceClient.DeleteTemporaryDirectoryAsync(m_oGuidSessionToConvert.ToString("N"), ServiceManager.GetLicenseKey());

            CursorNormal(this);

            SplashScreenManager.SplashScreen.ProgressBarProcess.Visibility = Visibility.Collapsed;
            SplashScreenManager.SplashScreen.ProgressBarProcess.Value = 0;
        }

        /// <summary>
        /// Converts the next document.
        /// </summary>
        /// <param name="L_oWCFServiceClient">The l_o WCF service client.</param>
        private void ConvertNextDocument(WCFServiceClient L_oWCFServiceClient)
        {
            //Increment index
            m_iCurrentIndextoFilenamesToConvert++;

            //Notify user of progression
            SplashScreenManager.SplashScreen.ProgressBarProcess.Value++;

            if (m_iCurrentIndextoFilenamesToConvert < m_oFilenamesToConvert.Count)
            {
                //Notify user
                SplashScreenManager.SplashScreen.MessageDetail = m_oFilenamesToConvert[m_iCurrentIndextoFilenamesToConvert];

                //Continue converting with next document
                L_oWCFServiceClient.ConvertDocumentAppendCompleted += L_oWCFServiceClient_ConvertDocumentAppendCompleted;
                L_oWCFServiceClient.ConvertDocumentAppendAsync(m_oGuidSessionToConvert.ToString("N"), m_oFilenamesToConvert[m_iCurrentIndextoFilenamesToConvert], UserId, ServiceManager.GetLicenseKey(), true);
            }
            else
            {
                //IF there is items who need finalizing
                if (m_oFilenamesToConvert.Count > 0)
                {
                    //Converting is finished
                    SplashScreenManager.SplashScreen.Message = Resx.GetLabel(ResxCommon.MSG_FINALIZING);
                    SplashScreenManager.SplashScreen.MessageDetail = String.Empty;

                    //Finalize converting
                    L_oWCFServiceClient.ConvertDocumentFinishCompleted += L_oWCFServiceClient_ConvertDocumentFinishCompleted;
                    L_oWCFServiceClient.ConvertDocumentFinishAsync(m_oGuidSessionToConvert.ToString("N"), UserId, ServiceManager.GetLicenseKey(), false);
                }
                else
                {
                    AbortMergePdf(L_oWCFServiceClient);
                }
            }
        }

        /// <summary>
        /// Handles the ConvertDocumentFinishCompleted event of the L_oWCFServiceClient control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Rio.Framework.WCFService.RioWcfServices.ConvertDocumentFinishCompletedEventArgs" /> instance containing the event data.</param>
        private void L_oWCFServiceClient_ConvertDocumentFinishCompleted(object sender, ConvertDocumentFinishCompletedEventArgs e)
        {
            WCFServiceClient L_oWCFServiceClient = ServiceManager.GetRioWCFServiceClient();

            SplashScreenManager.SplashScreen.ProgressBarProcess.Visibility = Visibility.Collapsed;
            SplashScreenManager.SplashScreen.ProgressBarProcess.Value = 0;

            //Delete temporary directory
            L_oWCFServiceClient.DeleteTemporaryDirectoryCompleted += (s, ev) =>
            {
                if (ev.Result.IsValid)
                {
                    //Delete all imported documen who have been converted
                    L_oWCFServiceClient = ServiceManager.GetRioWCFServiceClient();

                    L_oWCFServiceClient.DeleteImportDocumentCompleted += (o, ew) =>
                    {
                        if (ew.Error != null)
                        {
                            //Logger.Write("EXCEPTION : " + Environment.NewLine + e.Error.Message, Logger.Level.Error);
                            CursorNormal(this);
                        }
                        else
                        {
                            if (ew.Result.IsValid)
                            {
                                ListAllDocFileName.Remove(GetFileNameSelected);

                                ListAllDocFileName.Insert(0, Path.GetFileName(e.Result.Value));

                                LoadImageFromDocument(UserId, ListAllDocFileName, 0, false);
                            }
                            else
                            {
                                //Logger.Write("EXCEPTION : " + Environment.NewLine + e.Error.Message, Logger.Level.Error);
                                CursorNormal(this);
                            }
                        }
                    };

                    L_oWCFServiceClient.DeleteImportDocumentAsync(new ObservableCollection<string>(m_oFilenamesToConvert), UserId, ServiceManager.GetLicenseKey());
                }
            };

            L_oWCFServiceClient.DeleteTemporaryDirectoryAsync(m_oGuidSessionToConvert.ToString("N"), ServiceManager.GetLicenseKey());
        }

        /// <summary>
        /// Gets the selected files name to merge in PDF.
        /// </summary>
        /// <param name="p_oSelectedFilesName">Name of the p_o selected files.</param>
        /// <returns></returns>
        private new bool GetSelectedFilesNameToMergeInPDF(List<string> p_oSelectedFilesName)
        {
            Boolean l_bFileFormatOk = true;

            if (p_oSelectedFilesName == null)
                throw new ArgumentException("List must initilized before!");

            List<string> L_oListExtension = new List<string>();

            //Add the images file extension
            L_oListExtension.AddRange(from Enum item in EnumHelper.GetValues(typeof(Constant.ImageFileFormat))
                                      select Constant.szGetDescription(item));

            //Add the documents file format
            L_oListExtension.AddRange(from Enum item in EnumHelper.GetValues(typeof(Constant.DocumentFileFormat))
                                      select Constant.szGetDescription(item));

            if (GetFileNameSelected != null)
            {
                string L_szFileName = GetFileNameSelected;

                //The pdf merge is enable only with image file format (Rio.Applications.Web.Services.Constant.ImageFileFormat)
                if (L_oListExtension.Contains((Path.GetExtension(L_szFileName)).ToLower()))
                {
                    p_oSelectedFilesName.Add(L_szFileName);
                }
                else
                {
                    l_bFileFormatOk = false;

                    MessageBoxChildWindow L_oMessage = new MessageBoxChildWindow("", LabelMergePDFFormatFileError, MessageBoxButtons.Ok, MessageBoxIcon.Error);
                    L_oMessage.ShowDialog();
                }
            }

            return l_bFileFormatOk;
        }

        /// <summary>
        /// Dispatch Page/Page file PDF
        /// </summary>
        private void OnExplodePDF()
        {
            MessageBoxChildWindow L_oMessagesExplodePdf = new MessageBoxChildWindow("", Resx.GetLabel(ResxCommon.EXPLODE_PDF_QUESTION), MessageBoxButtons.YesNo, MessageBoxIcon.Question);
            L_oMessagesExplodePdf.Show();
            L_oMessagesExplodePdf.Closed += (s, ev) =>
            {
                if (L_oMessagesExplodePdf.Result == MessageBoxResult.Yes)
                {
                    CursorWait(this);

                    string l_szFileName = Utils.RemoveExtension(CurrentSelectedImage.Name);  // ItemVignette.Name have twice extension (ex: .tiff.jpg)
                    string l_szExtension = Path.GetExtension(l_szFileName);
                    if (l_szExtension.ToLower().Equals(".pdf"))
                    {
                        WCFServiceClient L_oWCFServiceClient = ServiceManager.GetRioWCFServiceClient();
                        L_oWCFServiceClient.ExplodePdfCompleted += L_oWCFServiceClient_ExplodePDFCompleted;
                        L_oWCFServiceClient.ExplodePdfAsync(l_szFileName, UserId, ServiceManager.GetLicenseKey());
                    }
                }
                else
                {
                    CursorNormal(this);
                }
            };
        }

        /// <summary>
        /// Handles the ExplodePDFCompleted event of the L_oWCFServiceClient control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Rio.Framework.WCFService.RioWcfServices.ExplodePdfCompletedEventArgs"/> instance containing the event data.</param>
        private void L_oWCFServiceClient_ExplodePDFCompleted(object sender, ExplodePdfCompletedEventArgs e)
        {
            if (e.Result != null)
            {
                GetThumbnailList(-1, this.CurrentSelectedDirectory);
            }

        }

        #endregion

        #region Search Text

        /// <summary>
        /// Searches the text inside the document.
        /// </summary>
        private void SearchTextInsideTheDocument()
        {
            SplashScreenManager.Wait(this);
            SplashScreenManager.SplashScreen.Message = "Recherche en cours";

            m_sCurrentSearchWord = SearchInput.MaskedText;
            m_oSearchPages = new List<int>();
            NextSearchPage.IsEnabled = false;
            PreviousSearchPage.IsEnabled = false;
            WCFServiceClient L_oWCFServiceClient = ServiceManager.GetRioWCFServiceClient();

            if (CurrentDisplayMode == AppDisplayMode.Search)
            {
                L_oWCFServiceClient.SearchTextInDocumentCompleted += L_oWCFServiceClient_SearchTextInDocumentCompleted;
                L_oWCFServiceClient.SearchTextInDocumentAsync(Path.Combine(ParameterStorage, GetFileNameSelected), m_sCurrentSearchWord, 0, ServiceManager.GetLicenseKey());
            }
            else
            {
                L_oWCFServiceClient.SearchTextInImportDocumentCompleted += L_oWCFServiceClient_SearchTextInImportDocumentCompleted;
                L_oWCFServiceClient.SearchTextInImportDocumentAsync(GetFileNameSelected, UserId, m_sCurrentSearchWord, 0, ServiceManager.GetLicenseKey());

            }
        }

        /// <summary>
        /// Handles the SearchTextInDocumentCompleted event of the L_oWCFServiceClient control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Rio.Framework.WCFService.RioWcfServices.SearchTextInDocumentCompletedEventArgs" /> instance containing the event data.</param>
        private void L_oWCFServiceClient_SearchTextInDocumentCompleted(object sender, SearchTextInDocumentCompletedEventArgs e)
        {
            SplashScreenManager.Stop(this);
            if (e.Error != null)
            {
                //Try to reconnect
                //RetryGetDocument((int)e.UserState, ErrorCodesEnums.ReturnObjectErrorCodesEnum.ServerNotFound, e.Error.Message, e.Error.StackTrace, false);
            }
            else
            {
                ManageSearchResult(e.Result);
            }
        }

        /// <summary>
        /// Handles the SearchTextInImportDocumentCompleted event of the L_oWCFServiceClient control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Rio.Framework.WCFService.RioWcfServices.SearchTextInImportDocumentCompletedEventArgs" /> instance containing the event data.</param>
        private void L_oWCFServiceClient_SearchTextInImportDocumentCompleted(object sender, SearchTextInImportDocumentCompletedEventArgs e)
        {
            SplashScreenManager.Stop(this);
            if (e.Error != null)
            {
                //Try to reconnect
                //RetryGetDocument((int)e.UserState, ErrorCodesEnums.ReturnObjectErrorCodesEnum.ServerNotFound, e.Error.Message, e.Error.StackTrace, false);
            }
            else
            {
                ManageSearchResult(e.Result);
            }
        }

        /// <summary>
        /// Manages the search result.
        /// </summary>
        /// <param name="p_oResult">The p_o result.</param>
        private void ManageSearchResult(ReturnLong p_oResult)
        {
            if (!p_oResult.IsValid)
            {
            }
            else
            {
                if (p_oResult.Value != -1)
                {
                    IndexPage = Convert.ToInt16(p_oResult.Value);
                    FreezeNavigation();
                    GetSourceDocument(Convert.ToInt16(p_oResult.Value), Convert.ToInt16(p_oResult.Value), true);

                    if (IndexPage < m_iNbOfPage)
                    {
                        NextSearchPage.IsEnabled = true;
                    }
                    else
                    {
                        NextSearchPage.IsEnabled = false;
                    }

                    m_oSearchPages.Add(IndexPage);

                    if (m_oSearchPages.Count > 1)
                    {
                        PreviousSearchPage.IsEnabled = true;
                    }
                }
                else
                {
                    MessageBoxChildWindow L_oMessage = new MessageBoxChildWindow("", m_sMsgEndOfTheDocument, MessageBoxButtons.Ok, MessageBoxIcon.Information);
                    L_oMessage.ShowDialog();

                    if (m_oSearchPages.Count > 0)
                    {
                        m_iLastSearchPage = m_oSearchPages[m_oSearchPages.Count - 1];
                    }
                    NextSearchPage.IsEnabled = false;

                }
            }
        }

        #endregion

        #region Key handles

        /// <summary>
        /// Desactives key down event.
        /// </summary>
        public void DeactivateKeyPress()
        {
            //this.KeyDown -= ImageViewer_KeyDown;
        }

        /// <summary>
        /// Active key down event.
        /// </summary>
        public void ActivateKeyPress()
        {
            //this.KeyDown += ImageViewer_KeyDown;
        }

        /// <summary>
        /// Key down handle
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ImageViewer_KeyDown(object sender, KeyEventArgs e)
        {
            //SUPPR
            if (e.Key == Key.Delete && (DocumentToolbar.CanDelete | CurrentDisplayMode == AppDisplayMode.Import))
            {
                OnItemDeleteClick();
                return;
            }

            // -
            if (e.Key == Key.Subtract)
            {
                OnZoomMoinsClick();
                return;
            }

            // +
            if (e.Key == Key.Add)
            {
                OnZoomPlusClick();
                return;
            }


            //Ctrl + X
            if (e.Key == Key.X && DocumentToolbar.CanDelete && CurrentDisplayMode == AppDisplayMode.Search)
            {
                if ((Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control)
                {
                    OnCutClick();
                    return;
                }
            }

            //Ctrl + C
            if (e.Key == Key.C && DocumentToolbar.CanDownload && CurrentDisplayMode == AppDisplayMode.Search)
            {
                if ((Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control)
                {
                    OnCopyClick();
                    return;
                }
            }

            //Ctrl + V
            if (e.Key == Key.V && DocumentToolbar.CanModify && CurrentDisplayMode == AppDisplayMode.Search)
            {
                if ((Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control)
                {
                    OnPasteClick();
                    return;
                }
            }
        }

        #endregion

        #region Versionning

        /// <summary>
        /// Loads the specific version.
        /// </summary>
        public void LoadSpecificVersion(VersioningItem Version, int selectedDocumentIndex)
        {
            versionRelativeFilepath = Version.DocumentPath;
            displayedVersion = Version;
            this.IndexPage = 1;

            this.LoadImageFromDocument(this.UserId, selectedDocumentIndex, true, Version.DocumentPath, Version.VersionId.ToString());
        }

        /// <summary>
        /// Clear version informations
        /// </summary>
        public void ClearVersion()
        {
            this.displayedVersion = null;
            this.versionRelativeFilepath = string.Empty;
            this.isOldVersionDisplayed = false;
        }

        /// <summary>
        /// Changes the consultation mode
        /// </summary>
        /// <param name="organization">Organization</param>
        /// <param name="folderType">Folder type</param>
        /// <param name="modeToApply">Mode to apply</param>
        /// <param name="isVersioningActivated">if set to <c>true</c> [is versioning activated].</param>
        public override void ChangeConsultationMode(NetBay.Core.BusinessEntities.Organization organization, NetBay.Core.BusinessEntities.FolderType folderType, ConsultationModeType modeToApply, bool isVersioningActivated = false)
        {
            //Apply rights before change the mode
            DocumentToolbar.SetUserPriviledges(folderType, organization);
            DocumentContextMenu.SetUserPriviledges(folderType, organization);

            DocumentToolbar.ConsultationMode = modeToApply;
            DocumentContextMenu.ConsultationMode = modeToApply;
            this.ConsultationMode = modeToApply;

            DocumentToolbar.IsVersioningEnabled = isVersioningActivated;
            DocumentContextMenu.IsVersioningEnabled = isVersioningActivated;

            switch (modeToApply)
            {
                case ConsultationModeType.Disable:
                case ConsultationModeType.Workflow:
                case ConsultationModeType.Trash:
                    isOldVersionDisplayed = false;
                    break;

                case ConsultationModeType.OldVersion:
                    isOldVersionDisplayed = true;
                    break;
            }
        }

        #endregion

        #region Document Toolbar

        /// <summary>
        /// Handles the DocumentRibbonBarEvent event of the DocumentToolbar control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="args">The <see cref="Rio.Framework.Pages.Events.DocumentRibbonBarEventArgs" /> instance containing the event data.</param>
        private void DocumentToolbar_DocumentRibbonBarEvent(object sender, Events.DocumentRibbonBarEventArgs args)
        {
            switch (args.DocumentRibbonBarMenuItem)
            {
                #region ScanImport
                case AppCode.Enums.DocumentRibbonBarMenuItems.Scan:
                    OnScanRequest();
                    break;
                case AppCode.Enums.DocumentRibbonBarMenuItems.Import:
                    OnImportRequest();
                    break;
                #endregion

                #region Display Mode
                case AppCode.Enums.DocumentRibbonBarMenuItems.DocumentMode:
                    break;
                case AppCode.Enums.DocumentRibbonBarMenuItems.ThumbnailsMode:
                    DocumentContextMenu.ManageContextMenuItemState();
                    DocumentToolbar.ManageToolbar();
                    DocumentToolbar.HideMinimizedPopup();
                    GoToThumbnailMode();
                    break;
                case AppCode.Enums.DocumentRibbonBarMenuItems.ListMode:
                    DocumentContextMenu.ManageContextMenuItemState();
                    DocumentToolbar.ManageToolbar();
                    DocumentToolbar.HideMinimizedPopup();
                    GoToListMode();
                    break;
                #endregion

                #region Fitting
                case AppCode.Enums.DocumentRibbonBarMenuItems.FitHeight:
                    IsInFitHeightMode = true;
                    SetViewerInFitMode(true);
                    break;
                case AppCode.Enums.DocumentRibbonBarMenuItems.FitWidth:
                    IsInFitHeightMode = false;
                    SetViewerInFitMode(false);
                    break;

                #endregion

                #region Zoom
                case AppCode.Enums.DocumentRibbonBarMenuItems.ZoomIn:
                    OnZoomPlusClick();
                    break;
                case AppCode.Enums.DocumentRibbonBarMenuItems.ZoomOut:
                    OnZoomMoinsClick();
                    break;
                #endregion

                #region Rotate
                case AppCode.Enums.DocumentRibbonBarMenuItems.RotateLeft:
                    ApplyRotateMenuClick(false);
                    CanRotateAllFiles();
                    break;
                case AppCode.Enums.DocumentRibbonBarMenuItems.RotateRight:
                    ApplyRotateMenuClick(true);
                    CanRotateAllFiles();
                    break;
                case AppCode.Enums.DocumentRibbonBarMenuItems.SaveModifications:
                    SaveModificationOnImage(ClickEvent.SaveModificationClick, false);
                    break;

                #endregion

                #region Search
                case AppCode.Enums.DocumentRibbonBarMenuItems.SearchNext:
                    NavigateIntoSearchDocument(true);
                    break;
                case AppCode.Enums.DocumentRibbonBarMenuItems.SearchPrevious:
                    NavigateIntoSearchDocument(false);
                    break;
                #endregion

                #region Actions
                case AppCode.Enums.DocumentRibbonBarMenuItems.SendEmail:
                    OnSendMailClick();
                    break;
                case AppCode.Enums.DocumentRibbonBarMenuItems.Delete:
                    OnItemDeleteClick();
                    break;
                case AppCode.Enums.DocumentRibbonBarMenuItems.MergePDF:
                    SaveModificationOnImage(ClickEvent.SaveModificationClick, true);
                    break;
                case AppCode.Enums.DocumentRibbonBarMenuItems.Download:
                    OnSaveDocumentClick();
                    break;
                case AppCode.Enums.DocumentRibbonBarMenuItems.Print:
                    OnPrintMenuClick();
                    break;
                case AppCode.Enums.DocumentRibbonBarMenuItems.DocumentPrint:
                    OnDocumentPrintMenuClick();
                    break;
                case AppCode.Enums.DocumentRibbonBarMenuItems.AddDocument:
                    OnAddDocumentEvent();
                    break;
                case AppCode.Enums.DocumentRibbonBarMenuItems.Split2:
                    ImportedDocumentRefreshed += UCViewer_ImportedDocumentRefreshed;
                    if (CurrentSelectedImage != null && CurrentSelectedImage.NumberPages <= 1) OnSplitImage(GetFileNameSelected, 2);
                    break;
                case AppCode.Enums.DocumentRibbonBarMenuItems.Split3:
                    ImportedDocumentRefreshed += UCViewer_ImportedDocumentRefreshed;
                    if (CurrentSelectedImage != null && CurrentSelectedImage.NumberPages <= 1) OnSplitImage(GetFileNameSelected, 3);
                    break;
                case AppCode.Enums.DocumentRibbonBarMenuItems.SplitPDF:
                    OnExplodePDF();
                    break;
                case DocumentRibbonBarMenuItems.FolderLink:
                    ShowFolderLinkWindow();
                    break;

                #endregion

                #region Edit
                case AppCode.Enums.DocumentRibbonBarMenuItems.Cut:
                    OnCutClick();
                    break;
                case AppCode.Enums.DocumentRibbonBarMenuItems.Copy:
                    OnCopyClick();
                    break;
                case AppCode.Enums.DocumentRibbonBarMenuItems.Paste:
                    OnPasteClick();
                    break;
                case AppCode.Enums.DocumentRibbonBarMenuItems.CheckOut:
                    OnCheckOutClick();
                    break;
                case AppCode.Enums.DocumentRibbonBarMenuItems.CheckIn:
                    OnCheckInClick();
                    break;
                #endregion

                #region Workflow
                case AppCode.Enums.DocumentRibbonBarMenuItems.Ventilate:
                    OnVentilClick();
                    break;
                #endregion

                #region Outlook
                case AppCode.Enums.DocumentRibbonBarMenuItems.OpenDirectory:
                    SaveModificationOnImage(ClickEvent.OpenDirectory);
                    break;
                case AppCode.Enums.DocumentRibbonBarMenuItems.ReturnDirectory:
                    SaveModificationOnImage(ClickEvent.ReturnDirectory);
                    break;

                #endregion

            }
        }

        #endregion

        #region NavigationToolBar

        /// <summary>
        /// Freeze the navigation during async call
        /// </summary>
        private void FreezeNavigation()
        {
            MaskedTextBoxGetPage.IsEnabled = false;
            FirstPage.IsEnabled = false;
            PreviousPage.IsEnabled = false;
            NextPage.IsEnabled = false;
            LastPage.IsEnabled = false;
        }

        /// <summary>
        /// Navigations the toolbar action performed.
        /// </summary>
        /// <param name="buttonName">Name of the button.</param>
        private void NavigationToolbarActionPerformed(string buttonName)
        {
            switch (buttonName.ToLowerInvariant())
            {
                #region Document Navigation

                case "firstdocument":
                    OnFirstDocument();
                    break;
                case "previousdocument":
                    OnPreviousDocument();
                    break;
                case "nextdocument":
                    OnNextDocument();
                    break;
                case "lastdocument":
                    OnLastDocument();
                    break;

                #endregion

                #region Page Navigation

                case "firstpage":
                    FirstPage_Click();
                    break;
                case "previouspage":
                    PreviousPage_Click();
                    break;
                case "nextpage":
                    NextPage_Click();
                    break;
                case "lastpage":
                    LastPage_Click();
                    break;

                #endregion

                #region Search Text

                case "searchtext":
                    SearchTextInsideTheDocument();
                    break;
                case "previoussearchpage":
                    PreviousSearchPage_Click();
                    break;
                case "nextsearchpage":
                    NextSearchPage_Click();
                    break;

                #endregion
            }
        }

        #region Document section

        /// <summary>
        /// Handles the Click event of the NextDocument control.
        /// </summary>
        private void OnNextDocument()
        {
            if (ModifyRotateList.Count != 0)
            {
                SaveModificationOnImage(ClickEvent.NextDocumentClick, false);
            }
            else
            {
                OnNextDocumentClick();
            }
            ManageToolbarState();
            EnableDisableMenu();

        }

        /// <summary>
        /// Handles the Click event of the PreviousDocument control.
        /// </summary>
        private void OnPreviousDocument()
        {
            if (ModifyRotateList.Count != 0)
            {
                SaveModificationOnImage(ClickEvent.PreviousDocumentClick, false);
            }
            else
            {
                OnPreviousDocumentClick();
            }
            ManageToolbarState();
            EnableDisableMenu();
        }

        /// <summary>
        /// Handles the Click event of the LastDocument control.
        /// </summary>
        private void OnLastDocument()
        {
            if (ModifyRotateList.Count != 0)
            {
                SaveModificationOnImage(ClickEvent.LastDocumentClick, false);
            }
            else
            {
                OnLastDocumentClick();
            }
            EnableDisableMenu();
        }

        /// <summary>
        /// Handles the Click event of the FirstDocument control.
        /// </summary>
        private void OnFirstDocument()
        {
            if (ModifyRotateList.Count != 0)
            {
                SaveModificationOnImage(ClickEvent.FirstDocumentClick, false);
            }
            else
            {
                OnFirstDocumentClick();
            }

            EnableDisableMenu();
        }


        /// <summary>
        /// Changes the document performed.
        /// </summary>
        /// <param name="key">The <see cref="System.Windows.Input.KeyEventArgs" /> instance containing the event data.</param>
        private void ChangeDocumentActionPerformed(KeyEventArgs key)
        {
            if (key != null && key.Key.Equals(Key.Enter))
            {
                if (!String.IsNullOrEmpty(MaskedTextBoxGetDocument.Value.ToString()))
                {
                    ClearModification();

                    long newIndex = Convert.ToInt32(MaskedTextBoxGetDocument.Value) - 1;
                    if (newIndex >= 0 && newIndex <= ListAllDocFileName.Count - 1)
                    {
                        SelectedDocumentIndex = Convert.ToInt32(MaskedTextBoxGetDocument.Value) - 1;
                        GetSourceDocument(IndexPage, IndexPage);
                    }
                }
            }
        }

        /// <summary>
        /// Update the menu for document's navigation on first document
        /// </summary>
        private void OnFirstDocumentClick()
        {
            OnDocumentChanging();
            ClearVersion();
            OldSelectedDocumentIndex = SelectedDocumentIndex;
            SelectedDocumentIndex = 0;
            IndexPage = 1;

            // Retreive the document
            GetSourceDocument(IndexPage, IndexPage, true);
        }

        /// <summary>
        /// Update the menu for document's navigation on Last document
        /// </summary>
        private void OnLastDocumentClick()
        {
            OnDocumentChanging();
            ClearVersion();
            OldSelectedDocumentIndex = SelectedDocumentIndex;
            SelectedDocumentIndex = ListAllDocFileName.Count - 1;
            IndexPage = 1;

            // Retreive the document
            GetSourceDocument(IndexPage, IndexPage, true);
        }

        /// <summary>
        /// Update the menu for document's navigation on previous document
        /// </summary>
        private void OnPreviousDocumentClick()
        {
            OnDocumentChanging();
            ClearVersion();
            OldSelectedDocumentIndex = SelectedDocumentIndex;
            SelectedDocumentIndex--;
            IndexPage = 1;

            // Retreive the document
            GetSourceDocument(IndexPage, IndexPage, true);
        }

        /// <summary>
        /// Update the menu for document's navigation on next document
        /// </summary>
        private void OnNextDocumentClick()
        {
            OnDocumentChanging();
            ClearVersion();
            OldSelectedDocumentIndex = SelectedDocumentIndex;
            SelectedDocumentIndex++;
            IndexPage = 1;

            // Retreive the document
            GetSourceDocument(IndexPage, IndexPage, true);
        }


        /// <summary>
        /// Update the menu for document's navigation
        /// </summary>
        private void UpdateNavigationForDocuments()
        {
            // Set mask property
            SetMaskProperty(MaskedTextBoxGetDocument, SelectedDocumentIndex + 1, ListAllDocFileName.Count);

            if (Convert.ToInt16(ListAllDocFileName.Count) <= 1)
            {
                FirstDocument.IsEnabled = false;
                PreviousDocument.IsEnabled = false;
                NextDocument.IsEnabled = false;
                LastDocument.IsEnabled = false;
            }
            else
            {
                if (Convert.ToInt16(SelectedDocumentIndex) <= 0)
                {
                    FirstDocument.IsEnabled = false;
                    PreviousDocument.IsEnabled = false;
                    NextDocument.IsEnabled = true;
                    LastDocument.IsEnabled = true;
                }
                else if (Convert.ToInt16(SelectedDocumentIndex) == Convert.ToInt16(ListAllDocFileName.Count - 1))
                {
                    FirstDocument.IsEnabled = true;
                    PreviousDocument.IsEnabled = true;
                    NextDocument.IsEnabled = false;
                    LastDocument.IsEnabled = false;
                }
                else
                {
                    FirstDocument.IsEnabled = true;
                    PreviousDocument.IsEnabled = true;
                    NextDocument.IsEnabled = true;
                    LastDocument.IsEnabled = true;
                }
            }

        }

        /// <summary>
        /// Handles the ValueChanging event of the MaskedTextBoxGetDocument control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Telerik.Windows.Controls.RadMaskedTextBoxValueChangingEventArgs" /> instance containing the event data.</param>
        private void MaskedTextBoxGetDocument_ValueChanging(object sender, RadMaskedTextBoxValueChangingEventArgs e)
        {
            // If user value is higher than document page number, cancel value changing event
            if (e.NewValue != null)
            {
                if (!String.IsNullOrEmpty(e.NewValue.ToString()))
                {
                    if (Convert.ToInt32(e.NewValue) > ListAllDocFileName.Count)
                    {
                        // Cancel event
                        e.Handled = true;
                    }
                }
            }
        }

        #endregion

        #region Page section

        /// <summary>
        /// Update the menu for pages's navigation
        /// </summary>
        private void UpdateNavigationForPages()
        {
            // Set mask property
            SetMaskPropertyForPages();

            if (m_iNbOfPage <= 1)
            {
                MaskedTextBoxGetPage.IsEnabled = false;
                FirstPage.IsEnabled = false;
                PreviousPage.IsEnabled = false;
                NextPage.IsEnabled = false;
                LastPage.IsEnabled = false;
            }
            else
            {
                MaskedTextBoxGetPage.IsEnabled = true;
                if (IndexPage == 1)
                {
                    FirstPage.IsEnabled = false;
                    PreviousPage.IsEnabled = false;
                    NextPage.IsEnabled = true;
                    LastPage.IsEnabled = true;
                }
                else if (IndexPage == m_iNbOfPage)
                {
                    FirstPage.IsEnabled = true;
                    PreviousPage.IsEnabled = true;
                    NextPage.IsEnabled = false;
                    LastPage.IsEnabled = false;
                }
                else
                {
                    FirstPage.IsEnabled = true;
                    PreviousPage.IsEnabled = true;
                    NextPage.IsEnabled = true;
                    LastPage.IsEnabled = true;
                }
            }
        }

        /// <summary>
        /// Initialize the mask property for the display of pages
        /// </summary>
        private void SetMaskPropertyForPages()
        {
            SetMaskProperty(MaskedTextBoxGetPage, IndexPage, m_iNbOfPage);
        }


        /// <summary>
        /// Handles the Click event of the FirstPage control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Telerik.Windows.RoutedEventArgs" /> instance containing the event data.</param>
        private void FirstPage_Click()
        {
            if (ModifyRotateList.Count != 0)
            {
                SaveModificationOnImage(ClickEvent.FirstPageClick, false);
            }
            else
            {
                OnFirstPageClick();
            }
        }

        /// <summary>
        /// Handles the Click event of the PreviousPage control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Telerik.Windows.RoutedEventArgs" /> instance containing the event data.</param>
        private void PreviousPage_Click()
        {
            if (ModifyRotateList.Count != 0)
            {
                SaveModificationOnImage(ClickEvent.PreviousPageClick, false);
            }
            else
            {
                OnPreviousPageClick();
            }
        }

        /// <summary>
        /// Handles the Click event of the NextPage control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Telerik.Windows.RoutedEventArgs" /> instance containing the event data.</param>
        private void NextPage_Click()
        {
            if (ModifyRotateList.Count != 0)
            {
                SaveModificationOnImage(ClickEvent.NextPageClick, false);
            }
            else
            {
                OnNextPageClick();
            }
        }

        /// <summary>
        /// Handles the Click event of the LastPage control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Telerik.Windows.RoutedEventArgs" /> instance containing the event data.</param>
        private void LastPage_Click()
        {
            if (ModifyRotateList.Count != 0)
            {
                SaveModificationOnImage(ClickEvent.LastPageClick, false);
            }
            else
            {
                OnLastPageClick();
            }
        }


        /// <summary>
        /// Called when [last page click].
        /// </summary>
        private void OnLastPageClick()
        {
            IndexPage = m_iNbOfPage;
            FreezeNavigation();
            GetSourceDocument(IndexPage, IndexPage);
        }

        /// <summary>
        /// Called when [next page click].
        /// </summary>
        private void OnNextPageClick()
        {
            IndexPage++;
            FreezeNavigation();
            GetSourceDocument(IndexPage, IndexPage);
        }

        /// <summary>
        /// Called when [first page click].
        /// </summary>
        private void OnFirstPageClick()
        {
            IndexPage = 1;
            FreezeNavigation();
            GetSourceDocument(IndexPage, IndexPage);
        }

        /// <summary>
        /// Called when [previous page click].
        /// </summary>
        private void OnPreviousPageClick()
        {
            IndexPage--;
            FreezeNavigation();
            GetSourceDocument(IndexPage, IndexPage);
        }

        /// <summary>
        /// Changes the document performed.
        /// </summary>
        /// <param name="key">The <see cref="System.Windows.Input.KeyEventArgs" /> instance containing the event data.</param>
        private void ChangePageActionPerformed(KeyEventArgs key)
        {
            // If Enter key press
            if (key.Key.Equals(Key.Enter))
            {
                // load user resuest page on viewer
                if (!String.IsNullOrEmpty(MaskedTextBoxGetPage.Value.ToString()))
                {
                    ClearModification();

                    IndexPage = Convert.ToInt32(MaskedTextBoxGetPage.Value);
                    GetSourceDocument(IndexPage, IndexPage);
                }
            }
        }

        /// <summary>
        /// Handles the MouseLeave event of the MaskedTextBoxGetPage control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.Input.MouseEventArgs" /> instance containing the event data.</param>
        private void MaskedTextBoxGetPage_MouseLeave(object sender, MouseEventArgs e)
        {
            this.Focus();
            RadMenuDown.Focus();
            Dispatcher.BeginInvoke(() => { MaskedTextBoxGetPage.Focus(); });
        }

        /// <summary>
        /// Handles the ValueChanging event of the MaskedTextBoxGetPage control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Telerik.Windows.Controls.RadMaskedTextBoxValueChangingEventArgs" /> instance containing the event data.</param>
        private void MaskedTextBoxGetPage_ValueChanging(object sender, RadMaskedTextBoxValueChangingEventArgs e)
        {
            // If user value is higher than document page number, cancel value changing event
            if (e.NewValue != null)
            {
                if (!String.IsNullOrEmpty(e.NewValue.ToString()))
                {
                    if (Convert.ToInt32(e.NewValue) > m_iNbOfPage)
                    {
                        // Cancel event
                        e.Handled = true;
                    }
                }
            }
        }


        #endregion

        #region Text Search Section

        /// <summary>
        /// Handles the Click event of the PreviousSearchPage control.
        /// </summary>
        private void PreviousSearchPage_Click()
        {
            if (m_oSearchPages != null)
            {
                int l_iPreviousPage = m_oSearchPages.Where<int>(sp => sp < IndexPage).LastOrDefault();
                if (l_iPreviousPage != 0)
                {
                    GetSourceDocument(l_iPreviousPage, l_iPreviousPage);
                    IndexPage = l_iPreviousPage;
                    NextSearchPage.IsEnabled = true;
                }

                if (m_oSearchPages.IndexOf(l_iPreviousPage) == 0)
                {
                    PreviousSearchPage.IsEnabled = false;
                }
            }
            else
            {
                SearchTextInsideTheDocument();
            }
        }

        /// <summary>
        /// Handles the Click event of the NextSearchPage control.
        /// </summary>
        private void NextSearchPage_Click()
        {
            if (m_oSearchPages != null)
            {
                int l_iNextPage = m_oSearchPages.Where(sp => sp > IndexPage).FirstOrDefault();
                if (l_iNextPage != 0)
                {
                    GetSourceDocument(l_iNextPage, l_iNextPage);
                    IndexPage = l_iNextPage;
                    PreviousSearchPage.IsEnabled = true;
                }
                else
                {
                    WCFServiceClient wcfClient = ServiceManager.GetRioWCFServiceClient();
                    if (CurrentDisplayMode == AppDisplayMode.Search)
                    {
                        wcfClient.SearchTextInDocumentCompleted += L_oWCFServiceClient_SearchTextInDocumentCompleted;
                        wcfClient.SearchTextInDocumentAsync(Path.Combine(ParameterStorage, GetFileNameSelected),
                                                            m_sCurrentSearchWord, IndexPage,
                                                            ServiceManager.GetLicenseKey());
                    }
                    else
                    {
                        wcfClient.SearchTextInImportDocumentCompleted +=
                            L_oWCFServiceClient_SearchTextInImportDocumentCompleted;
                        wcfClient.SearchTextInImportDocumentAsync(GetFileNameSelected, UserId, m_sCurrentSearchWord,
                                                                  IndexPage, ServiceManager.GetLicenseKey());
                    }
                }

                if (l_iNextPage == m_iLastSearchPage)
                {
                    NextSearchPage.IsEnabled = false;
                }
            }


        }

        /// <summary>
        /// Handles the MouseLeave event of the SearchInput control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.Input.MouseEventArgs" /> instance containing the event data.</param>
        private void SearchInput_MouseLeave(object sender, MouseEventArgs e)
        {
            this.Focus();
            RadMenuDown.Focus();
            Dispatcher.BeginInvoke(() => { SearchInput.Focus(); });
        }

        /// <summary>
        /// Handles the KeyDown event of the SearchInput control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.Input.KeyEventArgs" /> instance containing the event data.</param>
        private void SearchInput_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter)
            {
                SearchTextInsideTheDocument();
            }
        }

        /// <summary>
        /// Navigate into searched fulltext document list "m_oDocumentFulltextNameList"
        /// </summary>
        /// <param name="p_bIsNext">Way to go: Next or previous</param>
        private void NavigateIntoSearchDocument(bool p_bIsNext)
        {
            if (m_oDocumentFulltextNameList != null && m_oDocumentFulltextNameList.Count > 0)
            {
                OldSelectedDocumentIndex = SelectedDocumentIndex;
                Boolean l_bFound = false;
                int l_iSecurityLoop = m_oDocumentFulltextNameList.Count * 2;
                while (!l_bFound)
                {
                    if (p_bIsNext && SelectedDocumentIndex >= ListAllDocFileName.Count - 1)
                    {
                        SelectedDocumentIndex = 0;
                    }
                    else if (!p_bIsNext && SelectedDocumentIndex <= 0)
                    {
                        SelectedDocumentIndex = ListAllDocFileName.Count - 1;
                    }
                    else
                    {
                        if (p_bIsNext)
                        {
                            SelectedDocumentIndex++;
                        }
                        else
                        {
                            SelectedDocumentIndex--;
                        }
                    }

                    if (m_oDocumentFulltextNameList.Contains(ListAllDocFileName[SelectedDocumentIndex]))
                    {
                        l_bFound = true;
                        break;
                    }

                    //To avoid infinite loop
                    if (l_iSecurityLoop-- == 0)
                    {
                        break;
                    }
                }

                if (l_bFound)
                {
                    IndexPage = 1;
                    if (OldSelectedDocumentIndex != SelectedDocumentIndex)
                    {
                        // Retreive the document
                        GetSourceDocument(1, 1, true);
                        MaskedTextBoxGetDocument.Value = SelectedDocumentIndex;
                    }
                }
            }
        }

        #endregion


        #endregion
    }
}
